Hi I have a frontend being served for testing from localhost making request to backend running at api.whatify.io which is an Nginx server fronting a Django backend.
The client app code is:
const axiosApi = axios.create({
baseURL: API_URL,
withCredentials: true,
})
export async function post(url, data, config = {}) {
return axiosApi
.post(url, {...data }, {withCredentials: true})
.then(response => response.data)
.then(response => {
console.log("response is", response);
console.log("WOW GOT", response.headers);
console.log("CUSTOM", response.headers.get("Cache-Control"));
})
}
The request and response headers are as follows as seen from browser:
Request URL: https://api.whatify.io/auth/login
Request Method: POST
Status Code: 302
Remote Address: 54.194.218.202:443
Referrer Policy: strict-origin-when-cross-origin
Response Headers:
access-control-allow-credentials: true
access-control-allow-origin: http://localhost:5173
access-control-expose-headers: accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with, cache-control, pragma, Set-Cookie
content-length: 0
content-type: text/html; charset=utf-8
cross-origin-opener-policy: same-origin
date: Sun, 05 Feb 2023 01:21:28 GMT
location: /
referrer-policy: same-origin
server: nginx/1.21.6
set-cookie: csrftoken=zaBGdsPdVSEm1ZRvgNKuGxQcr2mRJvhh; expires=Sun, 04 Feb 2024
01:21:28 GMT; Max-Age=31449600; Path=/; SameSite=None; Secure
set-cookie: sessionid=z3gygehf6gcwuc5pdq2v8kzff61ipcss; expires=Sun, 19 Feb 2023 01:21:28 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=None; Secure
vary: Origin, Cookie
x-content-type-options: nosniff
x-frame-options: DENY
Request Headers
:authority: api.whatify.io
:method: POST
:path: /auth/login
:scheme: https
accept: application/json, text/plain, */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 44
content-type: application/json
origin: http://localhost:5173
referer: http://localhost:5173/
sec-ch-ua: "Not_A Brand";v="99", "Google Chrome";v="109", "Chromium";v="109"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36
In the console, I am trying to log the response headers when I get response:
console.log("WOW GOT", response.headers); // prints WOW GOT undefined
Why is there no headers being avilable to axios client when I can see them in browser?
Related
I know that this has been asked so many times, but none of the answers I've found seems to work. My app is React frontend and Flask backend via an api. I have just switched to axios from the usual await fetch and it keeps throwing CORS errors:
Access to XMLHttpRequest at 'http://127.0.0.1:5050/api/user/register' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
My code is thus:
const config = {
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json" ,
},
}
const customFetch = axios.create({
baseURL: 'http://127.0.0.1:5050',
});
export const registerUser = createAsyncThunk(
'user/registerUser',
async (user, thunkAPI) => {
try {
const resp=await customFetch.post('/api/user/register', user, config);
return resp.data ;
}catch (error) {
return thunkAPI.rejectWithValue(error.response.data.msg);
}
}
);
My server has
CORS(app)
now also added:
#app.after_request
def add_security_headers(resp):
resp.headers['Access-Control-Allow-Origin']='*'
resp.headers['Access-Control-Allow-Methods']='GET, POST, PUT, OPTIONS'
resp.headers["Access-Control-Allow-Headers"]="Access-Control-Request-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin, Origin, X-Requested-With, Content-Type, Accept"
return resp
and in any case it works ok for a standard:
await fetch(`${api_host}/api/user/register`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
data here ...
}),
});
its driving me mad, any clues? Thanks
UPDATE
Just in case there isn't enough info here are the request and response headers:
General
Request URL: http://127.0.0.1:5050/api/user/register
Request Method: POST
Status Code: 500
Referrer Policy: strict-origin-when-cross-origin
Request
POST /api/user/register HTTP/1.1
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 110
Content-Type: application/json
DNT: 1
Host: 127.0.0.1:5050
Origin: http://localhost:3000
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.27
sec-ch-ua: "Microsoft Edge";v="105", " Not;A Brand";v="99", "Chromium";v="105"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Response
HTTP/1.0 500 INTERNAL SERVER ERROR
Content-Type: text/html; charset=utf-8
X-XSS-Protection: 0
Connection: close
Server: Werkzeug/2.0.0 Python/3.8.10
Date: Fri, 09 Sep 2022 17:52:09 GMT
Once again, any suggestions gratefully received.
I added the following headers server-side, and it seems to have solved it.
I dont know why it stopped working when I switched axios. With standard asyc call it was fine.
resp.headers['Access-Control-Allow-Origin']='*'
resp.headers['Access-Control-Allow-Methods']='GET, POST, PUT, OPTIONS'
resp.headers["Access-Control-Allow-Headers"]="Access-Control-Request-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Headers,Access-Control-Allow-Origin, Origin, X-Requested-With, Content-Type, Accept"
I am trying to add Login with spring security JDBC authentication in spring boot and React. I added cors filter configuration to spring security config file to work with CORS. I can Login with when .csrf().disable() is disabled. but when I try to send same post request with with csrf token i am getting error "Request header field x-xsrf-token is not allowed by Access-Control-Allow-Headers in preflight response".
I tried solutions provided in other questios but it dosen't work for me.
response header
HTTP/1.1 500
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Credentials: true
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Content-Language: en-US
Transfer-Encoding: chunked
Date: Sun, 20 Jan 2019 06:23:40 GMT
Connection: close
request header
POST /login HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Content-Length: 81
Access-Control-Allow-Origin: http://localhost:3000
Accept: application/json, text/plain, */*
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://localhost:3000/login
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: JSESSIONID=5B64C3749B3DCBBB5072B827D59E8418
form data
username: vk%40gmail.com
password: admin
_csrf: 30955a56-abb5-443a-a029-d6b371f16e5a
I send csrf token to react app like this
CsrfToken token = (CsrfToken)request.getAttribute(CsrfToken.class.getName());
map.put("csrf", token.getToken());
this is Cors filter configuration
#Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowCredentials(true);
configuration.setAllowedHeaders(Arrays.asList("authorization", "Cache-Control", "content-type", "xsrf-token"));
configuration.setExposedHeaders(Arrays.asList("xsrf-token"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
This axios POST request
export const addProjectTask = (username,password,csrf,history) => async dispatch => {
axios.post('http://localhost:8080/login',
Qs.stringify({
username: username,
password: password,
}), {
headers: {
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
"X-XSRF-TOKEN": csrf,
// Authorization: 'Bearer ' + csrf,
"Content-Type": "application/x-www-form-urlencoded"
},
credentials: 'include',
})
.then(function (response) {
console.log(response);
history.push("/");
})
.catch(function (error) {
console.log(error);
});
};
what am i doing wrong here?
I have problem with sending CORS request with token in header.
Fetch code:
fetchApi() {
fetch('http://some-link.com',
{
headers: {
'Accept': 'application/json',
'auth-token': 'xxxxxxxxx'
},
method: "GET"
}).then(response => response.json())
.then(function(response){
this.setState({hits:response});
}).catch(function(error) { console.log(error); });
console.log(this.state.hits);
};
Console log:
Access to fetch at 'http://some-link.com' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field auth-token is not allowed by Access-Control-Allow-Headers in preflight response.
Network request log:
General
Request URL: http://some-link.com
Request Method: OPTIONS
Status Code: 200 OK
Remote Address: some_ip:80
Referrer Policy: no-referrer-when-downgrade
Response Headers
Access-Control-Allow-Headers: origin, x-requested-with, content-type, auth_token
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-cache, private
Connection: Keep-Alive
Content-Length: 8
Content-Type: application/json
Date: Tue, 13 Nov 2018 13:30:35 GMT
Keep-Alive: timeout=5, max=100
Server: Apache/2.4.10 (Debian)
Request Headers
Provisional headers are shown
Access-Control-Request-Headers: auth-token
Access-Control-Request-Method: GET
Origin: http://localhost:3000
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36
Any ideas what might be wrong?
You have to change the server settings to allow the header "auth-token".
Once you do this, your request will work.
You are currently allowing "auth_token", not "auth-token".
Alternatively, change the header name in the frontend like so:
headers: {
'Accept': 'application/json',
'auth_token': 'xxxxxxxxx'
}
I have my angularjs app on example.com and my laravel app on api.example.com
I modified my htaccess file so I can do cross domain ajax requests,
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET,POST,PUT,DELETE"
Header set Access-Control-Allow-Headers "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
</IfModule>
and set the domain value in config/session.php to .example.com
But when I make an api call the middleware response with a 401:
public function handle($request, Closure $next)
{
if ($this->auth->guest()) {
return response()->json([
'error' => 401,
'message' =>'Unauthorized.'],
401
);
}
return $next($request);
}
When I login via example.com/user/login?username=foo&password=bar I can pass the middleware without any problems.
Here is my api call
Request:
GET /modul HTTP/1.1
Host: api.reko.to
Connection: keep-alive
Accept: application/json, text/plain, */*
Origin: http://reko.to
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
Referer: http://reko.to/modul/all
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4,pt;q=0.2
Response
HTTP/1.1 401 Unauthorized
Date: Tue, 17 Nov 2015 11:22:11 GMT
Server: Apache/2.4.12 (Win32) OpenSSL/1.0.1l PHP/5.6.8
X-Powered-By: PHP/5.6.8
Cache-Control: no-cache
Set-Cookie: laravel_session=eyJpdiI6ImpWN0E5dEF0cndnXC9YUG52VU1XazlnPT0iLCJ2YWx1ZSI6IkNzY0JlbnlDbkRZNkQ2enpOdUtGaW92T0RIRmhtcHlcL0JyaERHU0V0YnN1bURHVzE4V1ZLam50MTNsaTh3Tm0xVWFZejdnVitYVHlTZ2R5WEw4eTY0QT09IiwibWFjIjoiZWI1ZTM2YjM1YjUxMTgyZmMxZTc5MzQzZWUzYzI0YWY1OGQwNmI5YzI1ZTFhNTZmNzM1MzA2MTM2NGNmNzk4ZiJ9; expires=Tue, 17-Nov-2015 13:22:12 GMT; Max-Age=7200; path=/; domain=.reko.to; httponly
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With
Content-Length: 39
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json
Here is my Login:
$http.post(apiUrl + 'user/login', $scope.user).success(function(result) {
$http.get(apiUrl + 'modul').success(function(result) {
console.log(result);
});
});
I have an AngularJS application. It sends out requests to another server for data and so there's an OPTIONS request goes out with every $HTTP call.
When I check with fiddler there are two calls. The Options that always returns a 200 OK and then the data call.
However when I check the $HTTP it seems that it's getting the first request ( the options request ) and not getting the second request the one with real data.
Can someone point me in the right direction with this?
Here's one example of the code that is not responding correctly:
.factory('isUsernameAvailable', function (appConstant, $q, $http) {
return function (username) {
var deferred = $q.defer();
// if (!angular.isDefined(username) || username == null || username == "" || username.length < 6 ) return deferred.resolve();
var url = appConstant.baseUrl + '/api/user/existsByName';
$http({
url: url,
method: "PUT",
data: {
userName: username
}
}).then(function (data) {
// Found the user, therefore not unique.
deferred.reject("User name is taken");
}, function (data) {
// User not found, therefore unique!
deferred.resolve();
});
return deferred.promise;
}
})
I expect it to be returning as success or failure depending on if it finds the username. But in this case it always responds as a fail/error.
Here are the requests being made:
OPTIONS http://localhost:3048/api/user/existsByName HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Access-Control-Request-Method: PUT
Origin: http://localhost:2757
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Access-Control-Request-Headers: accept, authorization, content-type
Accept: */*
Referer: http://localhost:2757/Auth/register
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
giving:
HTTP/1.1 200 OK
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:2757
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Headers: content-type
X-SourceFiles: =?UTF-8?B?QzpcR1xhYmlsaXRlc3Qtc2VydmVyXFdlYlJvbGVcYXBpXHVzZXJcZXhpc3RzQnlOYW1l?=
X-Powered-By: ASP.NET
Date: Mon, 12 Jan 2015 17:52:12 GMT
Content-Length: 0
Then:
PUT http://localhost:3048/api/user/existsByName HTTP/1.1
Host: localhost:3048
Connection: keep-alive
Content-Length: 35
Accept: application/json, text/plain, */*
Origin: http://localhost:2757
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Authorization: null
Content-Type: application/json;charset=UTF-8
Referer: http://localhost:2757/Auth/register
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
{"userName":"abdddcdefgg#live.com"}
giving:
HTTP/1.1 404 Not Found
Cache-Control: no-cache
Pragma: no-cache
Expires: -1
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: http://localhost:2757
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Custom-Header
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcR1xhYmlsaXRlc3Qtc2VydmVyXFdlYlJvbGVcYXBpXHVzZXJcZXhpc3RzQnlOYW1l?=
X-Powered-By: ASP.NET
Date: Mon, 12 Jan 2015 17:52:12 GMT
Content-Length: 0
The problem is even if the second request returns a 200 when I debug the success and error functions it still goes to the error function all of the time.
You should use JSONP to do cross domain JSON calls. Look at the documentation here: https://docs.angularjs.org/api/ng/service/$http#jsonp. Also, your referring page and the response from the OPTIONS request must have the appropriate CORS headers set or else the browser will refuse to send the request here are the header settings that I use.
Access-Control-Allow-Headers:Content-Type, Authorization, Content-Length, X-Requested-With, Accept, x-csrf-token, origin
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
To call $http.jsonp with a PUT request, you would set up a configuration such as
var config = {
method: 'POST',
data: { test: 'test' }
};
and then pass that into the $http.jsonp call
$http.jsonp('http://example.com', config);
Here is more documentation https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS and http://en.wikipedia.org/wiki/JSONP