dennnis
dennnis

Reputation: 44

Authorization header doesn't get sent in cross-origin request

Solution at the END.

My server was my problem... Shortly solution, I need to use express cors

Original POST:

First of ALL:
I have add Access-Control-Allow-Origin, Access-Control-Allow-Headers and i can access the server, but, i can't send data in the Header to the server.

So:
I am developing basically with Vue.js (with webpack to hot reload changes) and Express (with nodemon). So I have 2 separated servers:

My server has authotization with passport.js, using jwt token (this articles show how: authentication vuejs and express passport jwt token). But not the point, just to explain.

When I make a request (using axios, fetch, doesn't matter) when I send a request to my API from http://localhost:8080 (port 8080, webpack) to the server at http://localhost:3000/api/products they didn't receive the Authorization header.

If, i make a request from the same server, from http://localhost:3000/index.html (port 3000) to the server at http://localhost:3000/api/products they receive the Authorization header.

I don't know Why!

At the server I implement CORs policy like this:

//(...)
app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, access-control-request-headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, authorization, Access-Control-Allow-Credentials, X-Auth-Token, X-Accept-Charset,X-Accept");
  //res.header("Access-Control-Allow-Headers", "*");
  
  //res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
//(...)

At the client I send the header:

  // (...) Imports
  import axios from "axios";

  // (...) other code
  const http = axios.create ({
    baseURL: process.env.VUE_APP_ROOT_API,
    timeout: 1000,
    withCredentials: true,
    headers: {'Content-Type': 'application/json'},
  });

  /*   // -- I Have tried this too...
  http.interceptors.request.use (
    function (config) {
      if (token) config.headers.Authorization = `Bearer ${token}`;
      return config;
    },
    function (error) {
      return Promise.reject (error);
    }
  );      
  */

  http.get('http://localhost:3000/api/products', {headers : { authorization: `Bearer ${token}` } }).then(data => {

// (...) code after

When I test at the same server it Works, When in separated server they don't send a header to the server.

Here a gif to show the problem:

gif

CODE EXAMPLE TO TEST THE PROBLEM: https://github.com/dennnisk/cors_police_response_preflight_does_not_have_http_ok.git

I'm stuck...


**EDIT 1 **:

I Change the code part os axios, adding withCredentials: true, as suggested, but got the error: Access to XMLHttpRequest at 'http://localhost:3000/api/products' 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 credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

So, I change the server app.js from this:

(...)
app.use(function(req, res, next) {
   res.header('Access-Control-Allow-Origin', "*");
   res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
(...)

To this:

(...)
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', "http://localhost:8080/");
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');

(...)

And get this error: Access to XMLHttpRequest at 'http://localhost:3000/api/products' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

I think, something is wrong with the server config...


EDIT 2:

It was my server. Need to use express cors Posted a answer below...

Upvotes: 0

Views: 2770

Answers (2)

dennnis
dennnis

Reputation: 44

Solution to the problem

For some reason that I don't know, my CORS manual policy doesn't work correctly.

//(...)
app.use(function(req, res, next) {
  res.header('Access-Control-Allow-Origin', "*");
  res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
  res.header('Access-Control-Allow-Credentials', 'true');
  res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, access-control-request-headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, authorization, Access-Control-Allow-Credentials, X-Auth-Token, X-Accept-Charset,X-Accept");
  next();
});
//(...)

1 - So I eliminate that and install cors yarn add cors --save (or npm install cors --save)
2 - Add require for cors:

 var express = require('express');
 var cors = require('cors');  ///  <<======= Add here
 var path = require('path');

3 - Use cors before my "authentication" method, like:

// get authenticated data
app.use('/api/products', cors({credentials: true, origin: 'http://localhost:8080'}), isAutenticated(), function(req, res, next) {
  res.json({id: '1000', text: 'test'});
});

That's it. Works fine... finally, after almost 2 days...

I commit the solution at : https://github.com/dennnisk/cors_police_response_preflight_does_not_have_http_ok

Upvotes: 0

ƒernando Valle
ƒernando Valle

Reputation: 3714

You forgot add withCredentials: true in axios?

const myrequests = axios.create({
  withCredentials: true,
  ...
})

and after that:

myrequests.get('http://localhost:3000/api/products', {headers : { 
  authorization: `Bearer ${token}` } })
  .then((data) => { 
   // REST OF THE CODE
  })
// (...) code after

Upvotes: 1

Related Questions