In cross origin requests, the authorization header can be sent in two ways: either by the browser or specified along with the request. This article explains which CORS headers you need for each.

Authorization header

The Authorization HTTP header provides authentication information on a request. There are several types of authentication that use this header, and some are supported by browsers, such as basic authentication. When an unauthenticated request is received by the server, it will respond with a HTTP 401 Unauthorized response with a WWW-Authenticate header. This will trigger the browser to ask the user for credentials. The browser will then perform the same request, but include an Authorization header with the entered credentials.

In contrast, some applications use the Authorization header without any intervening from the browser. A JavaScript app may obtain a token from the server and send that with each request to authenticate the request. This is called bearer authentication and the Authorization header is often used to send the token.

Cross origin access with credentials

If you want to send an Authorization header along with a request to another site, that site has to notify the browser that that is permitted. After all, sites can’t just access each other’s pages. It would be insecure if this site could perform an AJAX request to your bank’s site, using the cookies from your browser. However, there are some use cases for cross-site access. In that case, the CORS HTTP response headers can grant access to another site. These are response headers, so the application that handles the request has to give its OK that the response is used by another application.

XHR requests with Authorization header

When performing a cross-origin request which includes authorization header, the server needs to respond with approval of the use of credentials. How this is done differs depending on whether the Authorization header is set by the browser or from your application.

By the browser

Browsers support HTTP basic authentication as described above, where the browser asks for a username and password and sends it with every subsequent request. To use this, you need to enable credentials on your request. This will send cookies, client-side certificates, and basic authentication information in the Authorization header along with the request. To do this, you need three things:

  • On the client, specify that you want to include credentials. Set Request.credentials to include.
  • On the server, respond with Access-Control-Allow-Credentials: true. This lets the client know that authenticated requests are permitted.
  • On the server, respond with Access-Control-Allow-Origin header, containing the origin that performs the request. You must specify a URL, a wildcard won’t work with authenticated requests.

The browser handles authentication, so the application won’t see a username or password. If the user is not yet authenticated to the other site, the browser may display a scary message:

Dialog asking for credentials, containing a warning that the credentials will be submitted to another site.

By the application

Instead of letting the browser handle authentication, it is possible to send an Authorization header with a request from JavaScript by just specifying the name and value of the header. It works just like any other header.

One of these is the header Access-Control-Allow-Credentials, which allows authentication information such as cookies, authorization headers and client certificates in a cross-origin request. Another response header that can be used is Access-Control-Allow-Headers, which can be used to whitelist the Authorization header.

You need three things:

  • On the client, specify the Authorization header you want to include in the request.
  • On the server, respond with Access-Control-Allow-Origin header, containing the origin that performs the request, or a wildcard.
  • On the server, respond with Access-Control-Allow-Headers: Authorization to inform the browser that the Authorization header in the request is permitted.

Test it out

On the demo page you can perform cross-origin requests using different request and response headers.

Conclusion

If you specify your own authorization header, it works just like any other header. If you want the browser to send along the authorization header, it works like a authenticated request.