Nginx using CORS with credentials - nginx

I'm working on building a web application that communicates with a Laravell API through an Nginx server. I tried following the directions on the Nginx website for wide open cors, but it doesn't like the wild card response when sending credentials.
Access to fetch at 'https://api.***.com/' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '' when the request's credentials mode is 'include'.
The API server requires a Bearer access token to authenticate, and each endpoint is at its own path on the server. What is the correct way to configure Nginx in this scenario?

The error message is right, you can't use a wildcard origin and credentials:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
For requests without credentials, the literal value "*" can be specified, as a wildcard; the value tells browsers to allow requesting code from any origin to access the resource. Attempting to use the wildcard with credentials will result in an error.
Instead, just pass back the actual origin, the one that arrived in the Origin HTTP header, then it will always match:
add_header Access-Control-Allow-Origin $http_origin always;

Related

No ‘Access-Control-Allow-Origin’ header is present using angular + WordPress

when i post the data using POST method in woocommerce api. i am getting cors issue
Access to fetch at 'http://localhost/wordpress/wc-api/v3/customers?oauth_consumer_key=ck_64d88e1fa3516e9f5a06b6053f02976a534d3f8f&oauth_nonce=zsu3ysEnFHhvrZt4Nc7H66Dgu28H20K7&oauth_signature_method=HMAC-SHA256&oauth_timestamp=1562587817&oauth_version=1.0&oauth_signature=KtFxvyQNklUlfCi6rNWyJ0DEJ6AS2ZbwbO44u%2FEqxG4%3D' from origin 'http://localhost:8100' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
You have to set a Access-Control-Allow-Origin header on each request to the server, if your server is on a different domain than the app on which you are making those requests (the server sets it as a response header). Adding that header tells the system that the external domain "localhost:8100" is allowed to make those requests.
You cannot circumvent this requirement in vanilla browsers, because it is a built in security feature to reduce CORS attacks
PS. different ports on the same domain are considered to be different domains. Thus example.com will get a 401 error, if you are making a request to example.com:8100. Same goes for localhost, or any other domain.
Example code from an Apache2 web server .conf file, that I personally use to set these headers.
SetEnvIf Origin "^http(s)?://(.+\.)?(staging.\xxx\.com|xxx\.com|xxx\.local|xxx\.local:4200|a2\.local)$" origin_is=$0
Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
Just replace the xxx.com domains with localhost:8100 or whatever else you need in that array. (if you are using Apache web server)
As a result, the Chrome network tab should have an Access-Control-Allow-Origin header on attached to the request

How can I get my express server to redirect the client to a different domain using cors?

I have an express server that already has cors middlewear enabled.
https://myapi.com
app.use(cors({ origin: true }));
I have a single page application that makes a request and is suppose to get redirect to paypal after. (It gets served from a different origin as listed below)
https://myAngularApp.com (some service)
http.post('https://myapi.com/create-payment', data);
So back in in the express server, I want to send them off to paypal for authentication:
app.post('/create-payment', (req, res) => {
res.redirect('https://www.sandbox.paypal.com/somewhere..');
})
Back in the client I get the following error:
Failed to load https://www.sandbox.paypal.com/somewhere: Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access.
Looking at the request my client makes to paypal, you can also see that the origin is null.
(Just to note, disabling app.use(cors({ origin: true })); won't allow the client to get a normal response from the server, so this already shows that the cors middleware is linked up.
Error when commenting out cors
// app.use(cors({ origin: true })); - Commented Out
Failed to load "https://myapi.com/create-payment": Redirect from
'https://myapi.com/create-payment' to
'https://www.sandbox.paypal.com/somewhere.' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource. Origin 'https://myAngularApp.com' is therefore not
allowed access.
What else do I need to setup on the express server so that the client can be redirected to paypal?
Redirects work like this:
Client makes HTTP request
Server makes HTTP response that includes an instruction to request a different URL
Client makes HTTP request to the different URL
Server (possibly a different server) makes HTTP response
If, at step 2, the server grants permission to read the response via CORS, then that grants permission for that request.
There is no way for the response at step 2 (which is being made by your server) to grant permission to read the response at step 4 (which is being made by PayPal's server).
If Paypal doesn't grant permission with CORS, then your JavaScript cannot read the response.
(Just imagine if that weren't the case: EvilHacker.Net grants permission with CORS, then redirects to GMail.com, and then EvilHacker can read all your email!)

Vue-Request not sending Authorization Header

I'm using VueJS with vue-request for http requests. I'm trying to subscribe an user to a Mailchimp list but Mailchimp uses BasicAuth, so I'm doing as such:
scope.$http.post('https://us15.api.mailchimp.com/3.0/lists/listid/members',
{...mydata...}, {headers: {Authorization: 'Basic myencodedAPIkey'}})
But I get an error from the API: 401 Unauthorized - Your request did not include an API key.
So I check the Network log on Chrome and the Authorization is on my headers like this: **Access-Control-Request-Headers: authorization** but it should be like **Authorization: myencodedAPIkey**
On the Console the error appears as:
XMLHttpRequest cannot load
https://us15.api.mailchimp.com/3.0/lists/listid/members. Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://127.0.0.1:8000' is therefore not allowed
access. The response had HTTP status code 401.
When I use Postman it works just fine as the header is correctly sent.
This problem seems to have been solved here with setting the header on every request
https://laracasts.com/discuss/channels/vue/how-to-solve-the-allow-control-allow-cross-in-the-vuejs-header-request-setting?page=2
and here through setting it once
Vue-Request not sending Authorization Header
You are getting CORS error, when you are trying to request from one host to another, and the 'another' part does not allow it to happen. To prevent this error you can use webpack proxy configuration, so this way you do not have cross origin request, but I don't know how you will deal with this in production environment if your api does not allow cross origin requests.
In a project I'm working on, our devServer configuration is as follow
proxy: {
'/api': {
target: 'http://localhost:8080/'
}
},
with this, any request happening on /api/any/url will be redirect to localhost:8080/api/any/url

Can a HTTP redirect instruct the client to strip a specific header from the request?

We have a service that redirects the user to an object in an S3 bucket. The authentication for that request is stored in the query portion of the URL.
I understand that the spec doesn't specify what is to be done with request headers in the case of a redirect, but implementations I've seen will strip the Authorization header when HTTP Basic is used.
What's interesting is that when we call our service through HTTP Basic authentication, it works fine. The client strips the Authorization header from the request and the file is delivered from S3.
But when we call our service using OAuth bearer tokens the Authorization header is left in for the redirect, causing S3 to return a 400 error response.
Is there a way for the server's redirect response to instruct the client to strip the Authorization header before accessing the response's Location header?

CORS - why is Access-control-allow-origin header necessary?

Premise:
When an site (http://example.com) tries to make a cross-origin request, the browser will send an HTTP request to the cross-origin server (http://other-server.com) with the header Origin: http://example.com. If the server at http://other-server.com approves http://example.com as a valid origin, then it will 1) Respond without error AND 2) set the response header to Access-control-allow-origin: http://example.com
My question is - why is it necessary to set the Access-control-allow-origin header in the response? Doesn't responding without error already acknowledge that the server (http://other-server.com) is allowing the cross-origin request?
This extra layer of acknowledgement gives servers a lot of flexibility over how they support CORS. For example:
1) A server has a lot of choices when setting the Access-Control-Allow-Origin header. It can use the * value to allow all clients, or it can limit the scope of clients by using the actual value of the origin (e.g. http://example.com). If a server does support CORS, but not for all origins, it could respond without error, but the Access-Control-Allow-Origin could be set to http://notyourorigin.com.
2) CORS allows even more flexibility via the Access-Control-Allow-Methods and Access-Control-Allow-Headers preflight response headers. These headers go beyond the simple binary success/error HTTP status, and provide more nuanced information about what is and is not supported in the server.
As the examples above point out, an error response without any context can be very confusing to the user. If you make a CORS request, and all you get back is an error response, you have no idea why that request failed. Are you doing the request wrong? Does the server support CORS at all? This can be very difficult to figure out without any accompanying information. The Access-Control-* gives more context to the user so they can effectively debug their CORS requests.

Resources