Angular2 http.get preflight issues - javascript

I am currently using angular2's HTTP to POST and GET data from my custom api.
The API is in PHP and the end points etc have been tested and work fine.
The issue I am getting is any time I set the GET Authorization header, I get the following error message in Chrome console:
Response for preflight has invalid HTTP status code 404
I have set my API's headers to allow access from remote origins with the following:
header("Access-Control-Allow-Origin: http://localhost:3000");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST, PUT, PATCH ,DELETE");
header("Access-Control-Allow-Headers: Authorization, Content-Type");
Yes I am running my angular project on localhost, I have a POST request that happens without the Authoriazation header set and it works fine, I have also removed the Authorization header from my GET request and it then works fine (But that end point needs the Authorization header to send my JWT to my API)
Am I doing something wrong? Should I be settings other headers, I have tested the endpoint in Postman and all is working fine.
EDIT
I have also edited my Hosts file to have a tld point to my local and also one for the API which is an IP on my local machine....
So my origin is: website.com
My API: api.website.com
I have changed my
Access-Control-Allow-Origin: http://website.com:3000

I found the issue.
My router was only accepting $_POST and $_GET methods,
Chrome sends a OPTIONS method before sending the POST or GET to confirm the Origin.
For now I have just added:
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS");
header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin");exit;
}
So now when a OPTION request comes through it just returns the headers that are needed to allow my POST and GET requests

The easiest way to handle this if you have control of the responding server is to add a response header for:
Access-Control-Allow-Origin: *
This will allow cross-domain Ajax. In PHP, you'll want to modify the response like so:
<?php header('Access-Control-Allow-Origin: *'); ?>
You can just put the Header set Access-Control-Allow-Origin * setting in the Apache configuration or htaccess file. It just work like a charm.
From the comments, this is an important note: the wildcard is going to allow any domain to send requests to your host. I recommend replacing the asterisk with a specific domain that you will be running scripts on. While you are going to live.
refer Origin is not allowed by Access-Control-Allow-Origin

Related

Unresolvable CORS issue! How to disable the same origin policy of Chrome on MacOS?

For a while, I keep facing a problem about CORS. I'm running an ExtJS app with localhost and during REST process on Delete process, it keeps giving this error:
Response for preflight has invalid HTTP status code 403.
I've already reached these topics;
Several CORS issues & ideas to fix # https://stackoverflow.com/a/35588856/7163711
Disable Chrome web security # https://stackoverflow.com/a/3177718/7163711
I did several things but none of them worked for me!
Using extension for CORS: Allow-Control-Allow-Origin: * and here is a screenshot of extension's settings:
I've Chrome Canary on MacOS and running it with web-security-disabled. The browser is opening with FLAG and notice that this is web-security-disabled mod but somehow it does not behave as expected. Here is the terminal command I've used to run it:
open -a /Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --args --disable-web-security --/ChromeDisabled
But it's not working as well! So what am I doing wrong? How can I solve this problem?
I guess you want to solve the puzzle why it gives Error 403. The problem lies on the server-side, not in the browser nor in ExtJS.
Error 403 means "Unauthorized". So, why are you unauthorized? And what is a "preflight"?
A preflight request is a special request sent to the backend by the browser using the OPTIONS HTTP method. It is sent before the actual request, and it is sent without headers, cookies or other authentication data. It should not return the data, only a few headers indicating from which domains CORS requests are allowed to access the URL, and which methods and headers they may send. If the browser finds that the response information allows it to send the actual request, it will send the actual request and process the returned data.
So, to support CORS, OPTIONS requests against the backend have to always go through unauthenticated, since no authentication information can be sent. Your backend, however, does not allow OPTIONS requests to go through unauthenticated.
You may want to check which authentication code you use and try to get OPTIONS requests around authentication (of course, they shouldn't return any data then). I have no knowledge about your backend technology, you may want to ask how to solve this in another question with the correct tags; in C# it would be like this (I guess you have similar functions at your disposal somehow):
[HttpOptions]
[AllowAnonymous]
public HttpResponseMessage GenerateDemoKey() {
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("Access-Control-Allow-Origin", "*");
response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS");
response.Headers.Add("Access-Control-Allow-Headers", "Origin, Content-Type, X-Auth-Token, X-Requested-With, Authorization");
return response;
}
So, if it's an OPTIONS request (line 1), to the URL .../GenerateDemoKey (line 3) it may go through unauthorized (line 2), and the response with Status 200: OK (line 4) has headers added that tell the browser that sites from any domain are allowed to access the real URL (line 5), as long as they use one of the six named methods (line 6) and send only the five named headers (line 7).
In PHP, on the other hand, you would add an if block to the start of your script, before you process the authentication:
<?php
if($_SERVER['REQUEST_METHOD']=="OPTIONS") {
header("Access-Control-Allow-Origin: *")
header("Access-Control-Allow-Methods: GET, POST*")
header("Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token, X-Requested-With, Authorization")
exit(0);
}
If you use htaccess to authenticate, you may have to add a rule to the htaccess file to allow OPTIONS requests to pass through. With the combination of htaccess and PHP, there's a huge security risk there - make double sure to only whitelist those URLs that you have checked won't return private information when called with the OPTIONS method.

Safari 10.1: XMLHttpRequest with query parameters cannot load due to access control checks

When trying a CORS request on Safari 10.1, on an URL which includes query parameters (e.g. https://example.com/api?v=1), Safari says
XMLHttpRequest cannot load due to access control checks
Chrome/Firefox works fine.
On requests from the page without the ?v=1, Safari works fine too.
I tried changing the server response header from
Access-Control-Allow-Origin: https://example.com
to
Access-Control-Allow-Origin: https://example.com/api?v=1
but that breaks Chrome.
Any suggestions?
You're running into CORS issues.
Some possible causes:
The header Access-Control-Allow-Origin can only be set on server side, not in your clients script. (You did not make clear you did that correctly.)
Are you sure the protocol (http vs https vs maybe even file) is exactly the same?
If you may have multiple sub domains you need to setup your config (e.g. Apache) with something like "^http(s)?://(.+\.)?test\.com$
.
The ^ marks the start of the line to prevent anything preceeding this url. You need a protocol and allowing both here. A subdomain is optional. And the $ marks the end of line (you don't need to set sub-pages, because origin is only host based).
As stated here adding Access-Control-Allow-Headers: Origin to the server configuration as well may be a solution. Try to compare the actual requests made my Safari to the successfull requests done by Firefox or Chrome to spot possible missing Headers as well (and maybe compare them to your server configuration as well).
If anyone comes across this error, it just occurred in the application I was building. In my case, it turned out to be a trailing / in the uri, which caused a 301 response, which was for some reason interpreted by Safari as a 500 response.
Trying following might work -
Access-Control-Allow-Origin: <origin> | *
The problem is because it is necessary to be more specific in the data of the cors this does not happen in the other operating systems that do interpret it
This one worked for me for a back in php
header ("Access-Control-Allow-Headers: X-API-KEY, Origin, X-Requested-With, Content-Type, Accept, Access-Control-Request-Method");
header ("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
header ("Allow: GET, POST, OPTIONS, PUT, DELETE");
$ method = $ _SERVER ['REQUEST_METHOD'];
if ($ method == "OPTIONS") {
     die ();
}
Your server needs to reply to the OPTIONS http method. Not only to GET/POST/PUT/DELETE. Safari silently requests this hidden in the background. You can discover this with a MITM-attack on the connection, e.g. Fiddler.
The OPTIONS request at least needs to respond with the Cross-Origin Resource Sharing (CORS) headers, e.g.:
Access-Control-Allow-Headers
Access-Control-Allow-Methods
Access-Control-Allow-Origin
Additionally: Your Web Application Firewall (WAF) or Application Security Manager (ASM) needs to allow the OPTIONS request to pass through to your server. Often this is blocked by default, because it gives some slivers of information about the attack surface variables (http methods & headers) used by your API.
You should check the method type you calling may be - PUT, POST, GET etc.

CORS access blocking

I might need some help here.
I was trying to establish a connection with XMLHttpRequest from JavaScript to a PHP Script on another origin.
First thing I noticed was that I got a error from this request which told me that there were header missing. I searched a bit and found this documentation. I modified the header like this:
JS
//this.mozSystem = true;
this.open("POST", url, true);
this.setRequestHeader("Content-type", "application/json");
this.setRequestHeader("ADDON-TO-SERVER", "");
this.setRequestHeader("Content-length", massage.length);
this.setRequestHeader("Connection", "close");
PHP
header("Content-type: application/json");
header("Access-Control-Allow-Origin: *");
header("Access-Control-Request-Method: POST");
header("Access-Control-Allow-Headers: ADDON-TO-SERVER,Content-type");
And it works ... but I am not sure why in
header("Access-Control-Allow-Headers: ADDON-TO-SERVER,Content-type");
Content-type is needed.
Mozilla told me to add this one, but I though that it would just need one custom header, and isn't Content-type a basic one ?
Could someone tell me why this is needed and tell me if I done everything like it is intended to.
Thanks for any help,
Feirell
As far as headers go in the context of CORS, a Content-type request header with the value of application/json is not considered a “basic one” (to borrow your wording).
In the context of CORS, a Content-type request header is only considered “basic” if its value is application/x-www-form-urlencoded, multipart/form-data, or text/plain.
So your browser will allow a Content-type: application/json request from your Web application to work as expected only if the server you are sending that request to explicitly indicates that it’s OK with receiving such requests. And the way a server does that is by responding with a Access-Control-Allow-Headersheader that contains Content-type.
The rationale for your browser enforcing that restriction is that unless a server explicitly indicates is it OK with certain kinds of cross-origin requests, CORS is not intended to allow Web applications to do any kind of programmatic cross-origin requests that do anything more than what a basic HTML form-element action have always been able to do cross-origin.
And so since before CORS came along, HTML page have always been restricted just to sending application/x-www-form-urlencoded, multipart/form-data, or text/plain requests cross-origin, that’s what the basic CORS behavior is restricted to unless the server opts-in for more.

WordPress JSON API - Request Header Error

I'm working with the WordPress JSON API plugin to make requests to get posts and etc from my blog.
When I try to access a simple url from browser it works perfectly, but when I try to access from my Ionic application this following erros occurs:
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
Do I need to do something from my WP blog to allow it?
It is most likely due to a cross-origin request. So try adding the below headers in your functions.php file.
function add_cors_http_header(){
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
}
add_action('init','add_cors_http_header');
Make sure that you haven't already used header in another file, or you will get a nasty error.
Hope it helps you.

CORS - How do 'preflight' an httprequest?

I am trying to make a cross domain HTTP request to WCF service (that I own). I have read several techniques for working with the cross domain scripting limitations. Because my service must accommodate both GET and POST requests I cannot implement some dynamic script tag whose src is the URL of a GET request. Since I am free to make changes at the server I have begun to try to implement a workaround that involves configuring the server responses to include the "Access-Control-Allow-Origin" header and 'preflight' requests with and OPTIONS request. I got the idea from this post : Getting CORS working
At the server side, my web method is adding 'Access-Control-Allow-Origin: *' to the HTTP response. I can see that responses do include this header now. My question is: How do I 'preflight' a request (OPTIONS)? I am using jQuery.getJSON to make the GET request but the browser cancels the request right away with the infamous:
Origin http://localhost is not allowed by Access-Control-Allow-Origin
Is anyone familiar with this CORS technique? What changes need to be made at the client to preflight my request?
Thanks!
During the preflight request, you should see the following two headers: Access-Control-Request-Method and Access-Control-Request-Headers. These request headers are asking the server for permissions to make the actual request. Your preflight response needs to acknowledge these headers in order for the actual request to work.
For example, suppose the browser makes a request with the following headers:
Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header
Your server should then respond with the following headers:
Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header
Pay special attention to the Access-Control-Allow-Headers response header. The value of this header should be the same headers in the Access-Control-Request-Headers request header, and it can not be '*'.
Once you send this response to the preflight request, the browser will make the actual request. You can learn more about CORS here: http://www.html5rocks.com/en/tutorials/cors/
Although this thread dates back to 2014, the issue can still be current to many of us. Here is how I dealt with it in a jQuery 1.12 /PHP 5.6 context:
jQuery sent its XHR request using only limited headers; only 'Origin' was sent.
No preflight request was needed.
The server only had to detect such a request, and add the "Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN'] header, after detecting that this was a cross-origin XHR.
PHP Code sample:
if (!empty($_SERVER['HTTP_ORIGIN'])) {
// Uh oh, this XHR comes from outer space...
// Use this opportunity to filter out referers that shouldn't be allowed to see this request
if (!preg_match('#\.partner\.domain\.net$#'))
die("End of the road if you're not my business partner.");
// otherwise oblige
header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
// local request, no need to send a specific header for CORS
}
In particular, don't add an exit; as no preflight is needed.
Solve the CORS issue by writing your custom middleware in Node.js with these simple steps.
don't need to set anything from the client, just a little change on the Node.js server will fix the problem.
create a middleware:
// in middleware/corsResolver.js
function corsResolver(req, res, next) {
// Website you wish to allow to connect
// running front-end application on port 3000
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type,Authorization');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
}
module.exports = corsResolver;
now edit your server.js (index.js or any main file that starts your node server) and add this middleware:
// server.js or indes.js
const corsResolver = require('path/to/resolver-middleware')
app.use(corsResolver) // -----------> applied middleware here
// other stuff

Categories

Resources