Angularjs set custom header parameters - javascript

In angularjs i must set a custom header for a POST
So i make:
var config = { 'Content-Type': 'application/x-www-form-urlencoded', 'TenantCode': 'MYTENANT', 'LoginType': 'PASSW' };
So i execute the post
$http.post(urlBase + '/Token', data, config)
Anyway when i inspect the request i have
OPTIONS /Token HTTP/1.1
Host: test.strokein.it
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:54599
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/46.0.2490.86 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://localhost:54599/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4
and i don't see my header parameter
Why? What's the problem?

I think your config needs to look something like this:
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded',
'TenantCode': 'MYTENANT',
'LoginType': 'PASSW'
}
};
Looking at this specification of config.

That is your preflight request.
You have a CORS problem because you are testing from localhost to test.strokein.it
Easy fix would be you upload your test script to your server.
But in general, browser will send one more request after it gets an OK CORS response from your server i.e.
'Access-Control-Allow-Origin' : '*'
'Access-Control-Allow-Methods': 'GET, OPTIONS, PUT'
'Access-Control-Allow-Headers': 'Content-Type'
Then you should see your custom headers along with data on that POST request.
Read more here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Related

Fetch API CORS error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response

I'm trying to get data from an API of mine and I'm getting this error message in Chrome:
Access to fetch at 'https://myapi.amazonaws.com/accounts' from origin 'http://localhost:3000'
has been blocked by CORS policy: Request header field authorization is not allowed by
Access-Control-Allow-Headers in preflight response.
Since it's CORS, Chrome is doing a OPTIONS preflight request, which gets a 204 response with the following headers back:
access-control-allow-credentials: true
access-control-allow-origin: *
access-control-max-age: 3600
access-control-request-headers: *
access-control-request-method: GET, POST, PUT, PATCH, OPTIONS, DELETE
apigw-requestid: R64AgjukPHcEJWQ=
charset: utf-8
date: Tue, 10 May 2022 17:27:05 GMT
Then it makes the desired POST request with the following headers:
accept: application/json
authorization: Bearer some.very.long.string
Referer: http://localhost:3000/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="101", "Google Chrome";v="101"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36
And finally, here is the base code for the request (JS Fetch API):
const result = await fetch(`${process.env.MY_API_URL}/accounts`, {
method: 'POST',
mode: 'cors',
headers: new Headers(
Accept: 'application/json',
'Accept-Encoding': 'gzip, deflate, br',
Connection: 'keep-alive',
Authorization: `Bearer ${accessToken}`,
),
body: JSON.stringify({
accountId,
name,
}),
})
if (!result.ok || result.status !== 200)
throw new Error("Couldn't get data")
const jsonResponse = await result.json()
return jsonResponse
Any thoughts on what might be going on?
You need to set access-control-allow-headers in the preflight response, e.g.:
access-control-allow-headers: *
You can read more about Access-Control-Request-Headers and Access-Control-Allow-Headers
The headers
access-control-request-headers: *
access-control-request-method: GET, POST, PUT, PATCH, OPTIONS, DELETE
belong into the request, not into the response. You probably also need to set access-control-allow-methods in the preflight response, e.g.:
access-control-allow-methods: GET, POST, PUT, PATCH, OPTIONS, DELETE

Setting http headers with angular

I'm tring to add a header called "access-token" to all my http request like this:
var app= angular.module("MainModule", ["ngRoute"]);
app.run(function($http){
$http.defaults.headers.common['access-token'] =ACCESSTOKEN;
})
and in my service:
service.get= function (x) {
console.log(ACCESSTOKEN)
return $http({
method: "GET",
headers: {
'Content-Type': 'application/json',
'access-token': ACCESSTOKEN
},
crossDomain: true,
url: GETSERVICE.replace("{id}", x),
dataType: 'json'
}).then(function (response) {
if (response.data) {
return response.data;
} else {
return $q.reject(response.data);
}
}, function (response) {
return $q.reject(response.data);
});
}
the problem is that i can't see the header in the network. There is only the OPTION request without my header.
my Back end cors configuration is like:
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, UPDATE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, access-token");
chain.doFilter(req, res);
Any ideas how to fix it?
TY
EDIT 1:
Here is the OPTION request without modifiy headers
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: access-token
Access-Control-Request-Method: GET
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:8081
Origin: http://localhost:9080
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
and whit modify headers (worked):
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7
Access-Control-Request-Headers: access-token
Access-Control-Request-Method: GET
access-token: 1520963789861
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:8081
Origin: http://localhost:9080
Pragma: no-cache
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
whit modify headers I have the token in the request
CORS exists to secure APIs so that random clients do not make calls to them.
JavaScript has to take permissions to be able to make calls to those APIs. Browser is supposed to do all the heavy lifting related to CORS. But the only requirement is that the server should return the following HTTP headers for an OPTIONS request from a client:
Access-Control-Allow-Origin: <Origin fetched from the request>
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, DELETE
Access-Control-Allow-Headers: <ACCESS-CONTROL-REQUEST-HEADERS fetched from request>
If that is NOT an option, then on the client side, following code can be added to prevent all OPTIONS requests, which compromises security:
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
$httpProvider.defaults.headers.get = {};
}]);
See: https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
That OPTIONS request is called "preflight request". It only checks if your client has a right to send a request at all (when a server has a configured CORS). If server responds positively then your browser automatically send a full request with all you provided headers.
$httpProvider or $http module:
//with the provider, in the app.config():
$httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
$http.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
Ok I will tell you what were the problem.
The genial man who write the rest api that I call in cross domain checked the value of the token also in the OPTION request going in null pointer.
Solved adding a filter for the option request.
TY for all

Fail to add an HTTP header

I'm trying to produce an HTTP request with an Authorization header:
$.ajax({
type: 'GET',
url: "https://subdomain.domain.com/login",
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa('username' + ":" + 'password'));
}})
But the request that's produced by this code does not contain an Authorization header:
OPTIONS /login HTTP/1.1
Host: subdomain.domain.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: http://localhost:3021
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/12.3.4567.890 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: /
Referer: http://localhost:3021/app.html
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: en-US,en;q=0.8,he;q=0.6
What am I doing wrong?
This may Solve your Problem.
$.ajax({
type: 'GET',
url: "https://subdomain.domain.com/login",
headers : {
"Authorization" : "Basic " + btoa('username' + ":" + 'password')
}
})
The problem was that I tried to make a cross-domain request do a server that does not allow CORS.
Therefore, the request I saw was a preflight request that used the OPTIONS method. If in this preflight request I had gotten the proper response CORS header, I would see my Authorization header in the real request. But since I did not pass the preflight OPTIONS request, I didn't have a real request, and therefore I didn't see the Authorization header.
I solved it by consuming the API using Node.js rather than the browser.

Why can I not see my HTTP headers in Chrome?

I am performing a fetch:
fetch(url, fetchOptions);
fetchOptions is configured like so:
var fetchOptions = {
method: options.method,
headers: getHeaders(),
mode: 'no-cors',
cache: 'no-cache',
};
function getHeaders() {
var headers = new Headers(); // Headers is part of the fetch API.
headers.append('User-ID', 'foo');
return headers;
}
Checking fetchOptions at runtime it looks as follows:
fetchOptions.headers.keys().next() // Object {done: false, value: "user-id"}
fetchOptions.headers.values().next() // Object {done: false, value: "foo"}
But user-id is nowhere to be found in the request headers per Chrome dev tools:
GET /whatever?a=long_name&searchTerm=g HTTP/1.1
Host: host:8787
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
accept: application/json
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Referer: http://localhost:23900/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,fr;q=0.6
Why can I not see my "User-ID" header in Chrome dev tools, and why does the header key appear to have been lowercased?
Incase someone else has a similar problem there were two possible culprits for this:
I might not have been starting Chrome with the correct flags.
The following didn't work when run from a Windows shortcut:
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" -enable-precise-memory-info -disable-web-security
The following did work when run from a Windows command prompt:
C:\whatever\48.0.2564.82\application\chrome.exe --disable-web-security --user-data-dir=C:\whatever\tmp\chrome
The addition of no-cors to the mode of the request might have caused an OPTIONS request to precede the GET request and the server did not support OPTIONS.

Angular POST cross origin error while POSTMAN works

I try to POST from my angular login service:
$http.post('https://xyz/login',
{
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'signature': 'asd'
}
And I get this error:
XMLHttpRequest cannot load https://xyz/login. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:1337' is therefore not allowed access.
I tried this headers:
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
And also these:
"Access-Control-Allow-Origin": "*";
"Access-Control-Allow-Headers": "X-Requested-With";
"Access-Control-Allow-Methods": "GET, POST", "PUT", "DELETE";
The interesting thing, is that the POSTMAN works.
What shoud I have to do?
Thanks.
Your request includes non-simple headers Content-type and signature which must be included in the response's Access-Control-Allow-Headers header.
(Content-type is sometimes a simple header, but only for particular values. application/json is not one of those values, and it causes Content-type to become non-simple.)
Add Content-type to Access-Control-Allow-Headers in your server's preflight response.
POSTMAN is not bound by the same-origin policy, so it does not require CORS support from the server.
Is your browser making an OPTIONS request before POSTing?
check the NET tab
I've had issues before where an OPTIONS request was being made by the browser or Angular (don't know which) and the server did not have ...
"Access-Control-Allow-Methods": "GET, POST", "PUT", "DELETE", "OPTIONS";
Not sure if you already have the information you need. But in my local web-server - when I make an http request using postman here is what it adds to the header:
headers:
{ host: 'localhost',
connection: 'keep-alive',
pragma: 'no-cache',
'cache-control': 'no-cache',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36',
accept: '/',
referer: 'http://localhost/',
'accept-encoding': 'gzip, deflate, sdch',
'accept-language': 'en-US,en;q=0.8' },
And here is what I see in the rawHeaders:
[ 'Host',
'localhost',
'Connection',
'keep-alive',
'Pragma',
'no-cache',
'Cache-Control',
'no-cache',
'User-Agent',
'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36',
'Accept',
'/',
'Referer',
'http://localhost/',
'Accept-Encoding',
'gzip, deflate, sdch',
'Accept-Language',
'en-US,en;q=0.8' ],
So perhaps you just need to fake your client to be a recognized browser client.

Categories

Resources