Setting http headers with angular - javascript

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

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

Fetch Request header not sending cookies in chrome (v90.0.44), working in Firefox(v88.0) (JS)

Really struggling on getting a Fetch API call to send cookies along in the request headers in Chrome (also they are not being set from 'Set-Cookie' response headers from returned API responses in Chrome). Both however, work on Firefox.
Feel like I've tried a million solutions here, can someone explain what I'm guessing is the SameSite issues for Chrome?
Our base api URL is https://stage-api-v2.cbb.play
Aliased hosts file for localhost:
127.0.0.1 localhost
127.0.0.1 local.cbb.play
Cookie that is set that we are trying to forward along
import * as cookie from 'cookie';
import { NextApiRequest, NextApiResponse } from 'next';
export default (req: NextApiRequest, res: NextApiResponse) => {
res.setHeader(
'Set-Cookie',
cookie.serialize('refresh_token', req.body.token, {
httpOnly: true,
maxAge: 60 * 60,
secure: process.env.NODE_ENV === 'production',
path: '/',
sameSite: 'lax',
domain: '.cbb.play',
})
);
res.statusCode = 200;
res.json({ success: true });
};
Front end code that calls the API:
async function renewSession(payload) {
return await fetch(process.env.BASE_URL + '/api/user/renew-session', {
method: 'POST',
credentials: 'include',
headers: { 'Content-type': 'application/json' },
body: JSON.stringify(payload)
})
}
Request header in Firefox:
POST /api/user/renew-session HTTP/2
Host: stage-api-v2.cbb.play
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: application/json
Accept-Language: en-CA,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate, br
Referer: http://local.cbb.play:3000/
Content-Type: application/json
Origin: http://local.cbb.play:3000
Connection: keep-alive
Cookie: refresh_token=a49d51basasdfg4a569cc43b8603ac916f72c0102ace7b463d9c2;
Pragma: no-cache
Cache-Control: no-cache
Content-Length: 0
TE: Trailers
Request Header in Chrome (no cookie):
:authority: stage-api-v2.cbb.play
:method: POST
:path: /api/user/renew-session
:scheme: https
accept: application/json
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
cache-control: no-cache
content-length: 0
content-type: application/json
origin: http://local.cbb.play:3000
pragma: no-cache
referer: http://local.cbb.play:3000
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"
sec-ch-ua-mobile: ?0
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36
Response Header: (Note, removed non-important properties)
access-control-allow-credentials: true
access-control-allow-headers: Set-Cookie, Credentials, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization
access-control-allow-methods: GET, HEAD, OPTIONS, POST, PUT, DELETE
access-control-allow-origin:http://local.cbb.play:3000
access-control-expose-headers: Content-Length,Content-Range,Set-cookie
content-encoding: gzip
content-type: application/json

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.

Angularjs set custom header parameters

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

jQuery - ajax - post - json request - doesn't have post body in some URL

I've been stuck at this for a while now. I have ajax request here:
$.ajax({
url: UPDATE_USER_INFO_URL ,
type: "POST",
dataType: "json",
contentType: "application/json",
data: JSON.stringify({user:'user'}),
success: function (data, textStatus) {
if(data["statusCode"] && data["statusCode"] == 1) {
_callback(1,data);
}
else {
_callback(0,data);
}
},
error: function (jqXHR, textStatus){
_callback(0, {});
}
});
If I set UPDATE_USER_INFO_URL to a specific URL, fiddler show nothing in the body. If I set UPDATE_USER_INFO_URL to something else (even invalid URL), it does put {user:'user'} in the body in fiddler.
With original UPDATE_USER_INFO_URL:
POST http://10.35.50.26:8080/SelfServiceWs/user/session/upduserinfo HTTP/1.1
Accept: application/json, text/javascript, ; q=0.01
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Referer: http://10.35.50.26:8080/SelfService/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: 10.35.50.26:8080
Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=0BF9D9CCCE9030E60AB0BCE5F6562CD8
Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAGAbAdAAAADw==
Content-Length: 0
Chage url to /SelfServiceWs/abcdef
POST http://10.35.50.26:8080/SelfServiceWs/abcdef HTTP/1.1
Accept: application/json, text/javascript; q=0.01
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Referer: http://10.35.50.26:8080/SelfService/
Accept-Language: en-us
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host: 10.35.50.26:8080
Content-Length: 15
Connection: Keep-Alive
Pragma: no-cache
Cookie: JSESSIONID=9E79779805579A7964E03AAD76DF043B
{"user":"user"}
I have many other ajax calls, all are working as expected.
It must be little thing that I am missing.
I figured this out.
I have an authentication servlet filter to url /user/ssoauth, unexpectedly (to me), it made eveything call to URL under /user path (including /user/session/upduserinfo) to send out Authorization header. Moved filter to /user/auth/ssoauth stop client to send authorization header when calling user/session/upduserinfo and fix the problem.
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/user/ssoauth</url-pattern>
</filter-mapping>
cause every client call to URL after /user to send Authorization header.
I learned something new today!
try this
data: JSON.stringify({'user':'user'}),

Categories

Resources