How to send headers while using jsonp proxy? - http-headers

I am trying to get data from web services from my app to load a list and to load more on scroll using pull refresh & ListPaging plugins. I tried this with flickr API and it works fine, but problem comes when I try to access our own services because they expect "Authorization" header with Base64 encoded data and "Accept" header to decide format of response.
This is how I have defined my store:
Ext.define('myshop.store.CatalogListStore',{
extend:'Ext.data.Store',
requires: [
'myshop.model.CatalogListItem'
],
config:{
model:'myshop.model.CatalogListItem',
autoLoad :true,
proxy: {
type: 'jsonp',
url: 'http://192.168.23.89:7003/xxx-service/test/catalog/list',
useDefaultXhrHeader : false,
withCredentials:true,
method : 'GET',
headers: {
'Accept': 'application/json',
'Authorization': 'Basic YX5iOmM='
},
extraParams: {
format : 'json',
pagesize : 10
},
reader: {
type: 'json',
rootProperty: 'categories.data'
}
}
}
}
This is what I see in Chrome's network console:
Request URL:http://192.168.23.89:7003/xxx-service/test/catalog/list?_dc=1354529083930&format=json&pagesize=10&page=1&start=0&limit=25&callback=Ext.data.JsonP.callback2
Request Method:GET
Status Code:403 Forbidden
**Request Headers**
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Host:192.168.23.89:7003
Referer:http://localhost/myshop/
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Ubuntu/12.04 Chromium/20.0.1132.47 Chrome/20.0.1132.47 Safari/536.11
**Query String Parameters**
_dc:1354529083930
format:json
pagesize:10
page:1
start:0
limit:25
callback:Ext.data.JsonP.callback2
Response Headersview source
Content-Length:0
Content-Type:text/xml
Date:Mon, 03 Dec 2012 10:04:40 GMT
Server:Apache-Coyote/1.1
If I use Poster to access these services with Authorization header I am able to see response but since Headers are not passed in request I am getting "403 forbidden" status.
If I use headers like this it works :
Ext.Ajax.request({
url: 'resources/data/templates.json',
headers: {
'Accept': 'application/json',
'Authorization': 'Basic T3JkZXJSZWxlYXNlUmVmcmVzaGVyfk9yZGVyUmVsZWFzZVJlZnJlc2hlcjpPcmRlclJlbGVhc2VSZWZyZXNoZXI='
},
success: function(rsp){
}
});
but I cannot do this because I want to use listPaging plugin.

JSONP Works buy inserting the request URL as a in the the page header, if you need to authenticate your request, you will have to put it in the URL eg:
'http://192.168.23.89:7003/xxx-service/test/catalog/list?auth=1223456'
Are you certain you need to use JSONP?
See this answer for more info

Related

How to get the set-cookie from http response that is set by server using express.js?

For the cookie that is attached to http request we use "req.headers.cookie". Just like that I want to be able to console log the set-cookie value.
Currently I'm using "res._headers" which logs
[Object: null prototype] {
'x-powered-by': 'Express',
location: 'secrets',
vary: 'Accept',
'content-type': 'text/html; charset=utf-8',
'content-length': '58',
'set-cookie': [
'connect.sid=s%3A0nacHXK6fTKoQwBsVNvjW659OltdoVMR.L38W5Exjqg7wHnx70MF8OQu05uOFzWrrxJCgZ41RX7o; Path=/; HttpOnly'
]
But how can I just log the connect.sid(set-cookie) value?
Tried: res._headers"

Request body missing from POST requests made using Postman scripting

I am trying to run a pre-request script for authenticating all my requests to the Spotify API. It works via the Postman GUI, but when I try to make the request via scripting, it fails because there is no body. Here is my code
const postRequest = {
url: pm.environment.get("spotifyAuthApi"),
method: "POST",
header: {
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "*/*",
"Content-Length": 29,
"Authorization": "Basic " + btoa(pm.environment.get("client_id") + pm.environment.get("client_secret"))
},
body: {
grant_type: "client_credentials",
}
}
I get a
error: "unsupported_grant_type"
error_description: "grant_type parameter is missing"
And when I examine the request via the postman console, there is no request body, even though the request was built exactly like my fetch token request that does the same thing successfully in postman, only via the GUI instead of via a pre-request script. I have searched far and wide about this issue and tried multiple variations of the body object but to no avail. Either the body object doesn't generate my desired field, or it doesn't get created at all.
Mode might be missing in the body object. Try this:
body: {
mode: 'raw',
raw: JSON.stringify({ grant_type: 'client_credentials' })
}
More details might be found in Postman docs for RequestBody.
If you're using urlencoded, the body of the request would be structured like this:
body: {
mode: 'urlencoded',
urlencoded: [
{ key: 'grant_type', value: 'client_credentials'}
]
}

Axios post request failing due to CORS but the same request using ajax is getting no issues

I am getting following error wile doing axios post request.
But when I use ajax request there is no issue:
request has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Ajax Request:
Axios request:
let payload = {
type: ["a", "b"],
category: ["a", "b"],
category: ["a", "b"],
accountNumber: "123"
};
var apiURL = this.$apiBaseURL + "/Product/ProductDetails";
$.ajax({
url: apiURL,
type: "POST",
data: { payload },
xhrFields: {
withCredentials: true
},
success: function (result) {
console.log(JSON.stringify(result));
}
});
this.$http.post(apiURL,payload,{withCredentials: true})
**UPDATE 1 **
I am still facing the same issue. Here I will share the request header in both ajax and axios request
AJAX Working code and request header :
{
var apiURL = this.$apiBaseURL + "/Request/MediaUpload";
$.ajax({
method: 'post',
processData: false,
contentType: false,
cache: false,
data: fileformData,
enctype: 'multipart/form-data',
url: apiURL,
xhrFields: {
withCredentials: true
}
});
}
Request header:
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Content-Length: 7610
Content-Type: multipart/form-data; boundary=----
WebKitFormBoundaryAjc8HwVPaRtQ5Iby
Host: localhost:62148
Origin: http://localhost:8989
Referer: http://localhost:8989/
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
AXIOS failing code and header
var apiURL = this.$apiBaseURL + "/Request/MediaUpload";
var self=this;
let config={
headers:{
'Content-Type': 'multipart/form-data'
}
}
this.$http.post(apiURL, { withCredentials: true },fileformData,
config)
Request Headers:
Provisional headers are shown
Accept: application/json, text/plain, */*
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:8989/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Here is my web api config where I have enabled cors
string origin = "http://localhost:8989";
EnableCorsAttribute cors = new EnableCorsAttribute(origin, "*", "*", "*");
cors.SupportsCredentials = true;
config.EnableCors(cors);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
**UPDATE 2 **
The CORS configuration at server side is done correctly thats why I am able to make the call successfully via AJAX.
Is this a known AXIOS issue which occurs only when we enable the windows authentication?
This issue arises because jQuery sends the request as application/x-www-form-urlencoded by default and does not send preflight request whereas axios sends as application/json and sends a preflight request i.e. OPTIONS before sending actual request.
One way it could work is by setting Content-type header to 'Content-Type': 'application/x-www-form-urlencoded' in axios.
You will have to change the settings on server side to get around this issue.
Add this in your web.config file:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Using default ajax won't send any OPTIONS request, but using axios does. This will enable accepting OPTIONS requests.

Meteor - how to submit an SSL certificate for *client* authentication in Meteor using a POST request?

EDIT: Updated Question here -
Based on # DoctorPangloss answer, I changed this to a server method. Below is the code. I'm not sure whether this is the right way to make the API call. The data returned is null from the server. Output is below the code.
Meteor.startup(function() {
var cert = Assets.getText('client-2048.p12');
Meteor.http.post(
"https://identitysso.betfair.com/api/certlogin",
{
headers:
{
"X-Application": "njhR7Q3ELfAZENlr",
"Content-Type": "application/x-www-form-urlencoded"
},
params: {
"username": "xxxx",
"password": "xxxx",
"pkcs12": cert,
"password": "xxxx"
}
},
function(error, result)
{
console.log(result);
}
);
});
Output after the API login call:
I20140529-16:38:37.220(5.5)? { statusCode: 404,
I20140529-16:38:37.220(5.5)? content: ' Lot of HTML data here '
I20140529-16:38:37.221(5.5)? headers:
I20140529-16:38:37.221(5.5)? { 'set-cookie':
I20140529-16:38:37.221(5.5)? [ 'wsid=7a5e0a81-e720-11e3-9af8-066b01d132ba; Domain=.betfair.com; Path=/',
I20140529-16:38:37.221(5.5)? 'vid=7a5e0a82-e720-11e3-9af8-066b01d132ba; Domain=.betfair.com; Expires=Sun, 26-May-2024 11:00:42 GMT; Path=/' ],
I20140529-16:38:37.222(5.5)? 'cache-control': 'no-cache,must-revalidate,no-store',
I20140529-16:38:37.222(5.5)? expires: '-1',
I20140529-16:38:37.222(5.5)? pragma: 'no-cache',
I20140529-16:38:37.222(5.5)? 'x-frame-options': 'DENY',
I20140529-16:38:37.222(5.5)? 'content-type': 'text/html;charset=UTF-8',
I20140529-16:38:37.222(5.5)? 'content-language': 'en-GB',
I20140529-16:38:37.222(5.5)? 'transfer-encoding': 'chunked',
I20140529-16:38:37.223(5.5)? date: 'Thu, 29 May 2014 11:00:42 GMT',
I20140529-16:38:37.223(5.5)? vary: 'Accept-Encoding' },
I20140529-16:38:37.223(5.5)? data: null }
Previous question:
A self-signed SSL cert needs to be sent to an external server to login. This is on localhost.
I'm sure I checked enough for an existing answer, but only this question comes close - Checking clients certificate in Meteor.
I'm trying to achieve BetFair's Non-interactive (Bot) login: https://api.developer.betfair.com/services/webapps/docs/display/1smk3cen4v3lu3yomq5qye0ni/Non-Interactive+%28bot%29+login
Here's the testcode on the client for a simple button click event:
Template.postsList.events({
'click .betfair': function() {
HTTP.call("POST", "https://identitysso.betfair.com/api/certlogin",
{headers: {
'X-Application' : 'njhR7Q3ELfAZENlr',
'Accept': 'application/json',
'Content-type' : 'application/x-www-form-urlencoded'
},
params: {
'username': 'xxxxxx',
'password': 'xxxxxx'
},
options: {
cert: fs.readFileSync('/Users/mmapp/client-2048.crt'),
requestCert: false,
rejectUnauthorized: false
}
},
function (error, result) {
if (!error) {
console.log("Looks like its logging in...");
}
});
}
});
I'm aware of the possible problems:
fs.readFileSync only works in npm/node.js?
Meteor needs something like nginx to handle SSL?
Should the above code be running from the server block of meteor?
Should Npm.require("fs") be used somewhere?
How do we achieve this login process in Meteor?
I'm a beginner and any help would be greatly appreciated! Thanks.
fs.readFileSync works neither in client or server. Checkout Assets.getText to read a certificate from the server.
If you want a client to provide a cert to BetFair, prompt for the file using an input and read the text data with Javascript. http://www.html5rocks.com/en/tutorials/file/dndfiles/ has a good overview on ways to read files in the browser. Note, some certificates have funky permissions to prevent you from, e.g., uploading the certificate to some browser.
You can process the result as follows:
function (error, result) {
// From their website, the result is something like {"sessionToken":"Zx8i4oigut5nc+l4L8qFb0DSxG+mwLn2t0AMGFxjrMJI=","loginStatus":"SUCCESS"}
if (result.data.loginStatus === "SUCCESS") {
Session.set("botFairSessionToken", result.data.sessionToken);
}
}
Depending on what you want to do, you should probably do this call on an Accounts.onCreateUser handler on the server. Instead of Session.set use Meteor.users.update({_id: this.userId}, {$set: {"services.botFair.sessionToken": result.data.sessionToken}});
// Handler for a call inside a server method body:
function (error, result) {
// From their website, the result is something like {"sessionToken":"Zx8i4oigut5nc+l4L8qFb0DSxG+mwLn2t0AMGFxjrMJI=","loginStatus":"SUCCESS"}
if (result.data.loginStatus === "SUCCESS") {
Meteor.users.update({_id: this.userId},
{$set: {"services.botFair.sessionToken": result.data.sessionToken}})
}
}
data is only populated if the response includes a Content-Type: application/json header. You write that content has a lot of HTML data so I assume the response is HTML. If so, then this is the correct behavior.
From the docs:
If the response headers indicate JSON content, this contains the body
of the document parsed as a JSON object.

ajax post works vs. angularjs $http does not work w/ ASP.NET MVC 4

I have two projects client side and server side.
Client side project is pure htmljs. Server side is ASP.NET MVC 4 and Web Api.
Because there are two projects I need to enable CROS functionality.
I added into server's webconfig:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
Ajax Post version which is working:
$.post(url, appContext).done(
function(data, textStatus, jqXHR) {
successFn(data, textStatus);
})
.fail(
function(jqXHR, textStatus, err) {
errorFn(err, textStatus);
});
angular $http Post version which is NOT working:
$http({
url: url,
method: 'POST',
params: { appContext: appContext },
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
/*'Accept': 'text/json'*/}
}).success(successFn).error(errorFn);
When I use $http I am getting two errors:
OPTIONS url 405 (Method Not Allowed)
POST url 500 (Internal Server Error)
ASP.NET MVC method is
[System.Web.Http.HttpPost]
public List<Module> GetModules([FromBody]SessionContext appContext)
{
return CreateModules();
}
EDIT:
Angular model's configuration:
var emsApp = angular.module('EmsWeb', ['ui.bootstrap']);
emsApp.config(['$routeProvider', '$httpProvider', function($routeProvider, $httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}]);
Headers of OPTIONS request that I see in browser:
Request URL:http://localhost/EmsWeb/api/ModuleApi/GetModules?appContext=%7B%22globalDate%22%3A%22Mon%2C%2008%20Jul%202013%2013%3A09%3A35%20GMT%22%2C%22userToken%22%3A%22AlexToken%22%7D
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Request Headers
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, origin, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
DNT:1
Host:localhost
Origin:http://localhost:50463
Referer:http://localhost:50463/index.html
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.116 Safari/537.36
Query String Parametersview sourceview URL encoded
appContext:{"globalDate":"Mon, 08 Jul 2013 13:09:35 GMT","userToken":"AlexToken"}
Response Headers
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:76
Content-Type:application/json; charset=utf-8
Date:Mon, 08 Jul 2013 13:09:35 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Any ideas why angular way does not work are appreciated?
Update the issue as it turns out to be quite silly:
because I used params and instead of data in:
$http({
url: url,
method: 'POST',
params: { appContext: appContext },
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
/*'Accept': 'text/json'*/}
}).success(successFn).error(errorFn);
angular converted to GetRequest. No need for ContentType either.
so actual code is
$http({method: 'POST',
url: url,
data: appCtx,
}).success(successFn).error(errorFn);
so ALMOST resolved, I see that angular still issues OPTIONS request that fails but post request goes through...
so any ideas on that one are appreciated
My issue were due to two reasons:
I used params and instead of data in
$http({
url: url,
method: 'POST',
params: { appContext: appContext },
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
/*'Accept': 'text/json'*/}
}).success(successFn).error(errorFn);
angular converted to GetRequest. No need for ContentType either. so actual code is
$http({method: 'POST',
url: url,
data: appCtx,
}).success(successFn).error(errorFn);
on the server side
I needed something handling OPTIONS request. One way is to decorate method w/ [System.Web.Http.AcceptVerbs("OPTIONS")], which I do not think the best way.
Another way is to add Custom Message Handler.
I am still researching it...
If your ajax is working then it looks like the angular side of things isn't configured. Add this before you use $http (in your controller setup).
$http.defaults.useXDomain = true;
See this guys jsfiddle for a working example: http://jsfiddle.net/ricardohbin/E3YEt/
EDIT: Further to your comment and edit to the question, this post might help you: http://www.codeguru.com/csharp/.net/net_asp/using-cross-origin-resource-sharing-cors-in-asp.net-web-api.html
-Be sure about the syntax of get and Post and the way of sending parameters
-Check the expected Parameter that you expect at the destination action or method and be sure that the sending one and receiving one are the same.