POST method not being called after OPTIONS - angularjs

I'm trying to call an API from an angularjs application
var url = "...";
var myObject = {...};
var config = {
headers : {
'Content-Type': 'application/json;charset=utf-8;'
}
};
$http.post(url, myObject, config).then(function(result){...});
Because it's a cross-origin request, it does the preflight, so it calls the OPTIONS method.
This is the request header:
Host: ...
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: */*
Accept-Language: pt-BR
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Referer: http://localhost:9000/....
Origin: http://localhost:9000
DNT: 1
Connection: keep-alive
It returns as 200 OK, with the response header:
{
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-store, no-cache, must-revalidate
Content-Length: 0
Content-Type: text/html; charset=utf-8
Date: Fri, 01 Nov 2019 14:31:29 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Server: Microsoft-IIS/10.0
Vary: X-Requested-With
X-Frame-Options: GOFORIT
X-Powered-By: Nette Framework, ASP.NET
}
But it doesn't do the POST call afterwards. I tried calling the POST method directly through POSTMAN and it returned just fine. Is there something I'm missing?
EDIT: Heres the console error:
Possibly unhandled rejection:
{
"data":null,
"status":-1,
"config":{
"method":"POST",
"transformRequest":[null],
"transformResponse":[null],
"jsonpCallbackParam":"callback",
"headers":{
"Content-Type":"application/json;charset=utf-8;",
"Accept":"application/json, text/plain, */*"
},
"url":"...",
"data":{...},
"cached":false
},
"statusText":"",
"xhrStatus":"error"
}

The OPTIONS request has these headers set:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
so it is asking whether it can do a POST request including the "content-type" header.
The server responds with:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin: *
but it missing "Access-Control-Allow-Headers" response header:
Access-Control-Allow-Headers: content-type
Add this to the OPTIONS response and you should be good.
Possible, the error message in the console is
Reason: missing token ‘content-type’ in CORS header ‘Access-Control-Allow-Headers’ from CORS preflight channel*
which is self-explanatory.

add the additional header to your web.config like so...
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
</customHeaders>
</httpProtocol>

Related

React Axios CORS request unable to see any response header

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?

How to send CORS request from React?

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'
}

Unauthorized laravel api call at subdomain after successful authentication

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);
});
});

Web Api 2 does an OPTIONS request with a 503 error?

I have tried everything regarding the issue I am having with CORS with Web Api 2 and Angular.
I have downloaded the nuget package for CORS for the Web API.
I have enabled CORS in my controllers.
I added the following to my api web.config:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, HEAD" />
<add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />
</customHeaders>
</httpProtocol>
I added the following method to my controller:
public HttpResponseMessage Options()
{
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
}
And I have put the EnableCorsAttribute at the top of the controller.
After this, when I make my POST, I get the following request from within fiddler:
OPTIONS http://api.carb-stage.derivesystems.com/api/Recaptcha/Post HTTP/1.1
Host: api.carb-stage.derivesystems.com
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: POST
Origin: http://carb-stage.derivesystems.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Access-Control-Request-Headers: accept, content-type
Accept: */*
Referer: http://carb-stage.derivesystems.com/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
And this is the response I get:
HTTP/1.1 503 Service Unavailable
Content-Type: text/html; charset=us-ascii
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 29 Sep 2015 20:10:49 GMT
Connection: close
Content-Length: 326

backbonejs + cors and save() method

I'm trying to execute a POST throw the save method. Here is my model.
app.Models.Dummy = Backbone.Model.extend({
initialize: function () {
url = 'http://anotherdomain/Hello/';
},
});
When i execute:
dummy.save({text : "greg"}, {
success : function(){
console.log('Ok!');
},
error: function(){
console.log('Error');
}
});
The request is fired with an OPTIONS header (code 200) but the POST request is never fired.
However When i execute:
$.ajax({
type: 'POST',
url: "http://anotherdomain/Hello/",
data: {text:"greg"},
success: function(r) { alert(r.Result) },
dataType: "application/json"
});
it's works!
Does i need to override something in backbone?
EDIT:
The request is:
OPTIONS http://anotherdomain/Hello/ HTTP/1.1
Host: anotherdomain
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/17.0 Firefox/17.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Origin: http://mydomain
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Pragma: no-cache
Cache-Control: no-cache
and the response is:
HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 0
Server: Microsoft-IIS/7.5
Set-Cookie: ARRAffinity=611c389e4fd6c5d83202b700ce5627f6e0850faf0604f13c25903b4662919f36;Path=/;Domain=anotherdomain
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
X-Powered-By: ARR/2.5
X-Powered-By: ASP.NET
Date: Wed, 05 Dec 2012 18:44:27 GMT
That's not a valid OPTIONS response for CORS. The response needs to include headers that tell the browser what's allowed. For example (taken from MDN):
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER
I know you said that the $.ajax worked but based on this CORS response I doubt that is accurate and suggest you double check. Under the covers, backbone is itself just using $.ajax

Resources