Заголовок авторизации HTTP-запроса не отправляется на сервер при разработке с использованием 2 веб-пакетов ... Политика CORS: у него нет статуса HTTP ok - PullRequest
0 голосов
/ 03 января 2019

Решение в КОНЦЕ.

Мой сервер был моей проблемой ... Вскоре решение, мне нужно использовать Express Cors

Исходное сообщение:

First of ALL:
У меня есть дополнительные Access-Control-Allow-Origin, Access-Control-Allow-Headers и я могу получить доступ к серверу, но я не могу отправить данные вЗаголовок к серверу.

Итак:
Я разрабатываю в основном с Vue.js (с веб-пакетом для горячей перезагрузки изменений) и Express (с nodemon).Итак, у меня есть 2 отдельных сервера:

  • Первый: бэкэнд (сервер), работающий по адресу: http://localhost:3000 с nodemon
  • Второй: внешний интерфейс (клиент), работающий по адресу: http://localhost:8080 с веб-пакетом-dev-server (для горячей перезагрузки изменений vuejs) будет разрабатываться в одностраничном приложении.

Мой сервер имеет авторизацию с помощью passport.js с использованием токена jwt (в этих статьях показано, как: аутентификация vuejs и экспресс-паспорт jwt token ).Но не в этом дело, просто для объяснения.

Когда я делаю запрос (используя axios, fetch, не имеет значения), когда я отправляю запрос в мой API с http://localhost:8080 ( port 8080,webpack ) на сервер в http://localhost:3000/api/products они не получили заголовок Authorization.

Если я сделаю запрос с того же сервера, с http://localhost:3000/index.html ( порт 3000 ) на сервер на http://localhost:3000/api/products, они получат * Authorizationheader.

Я не знаю, почему!

На сервере я реализую политику CORs следующим образом:

//(...)
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();
});
//(...)

На клиенте я отправляю заголовок:

  // (...) 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

Когда я тестирую на том же сервере, он работает, когда на отдельном сервере они не отправляют заголовок на сервер.

Здесь gif, чтобы показать проблему:

gif

ПРИМЕР КОДА ДЛЯ ТЕСТИРОВАНИЯ ПРОБЛЕМЫ: https://github.com/dennnisk/cors_police_response_preflight_does_not_have_http_ok.git

Я застрял ...


** РЕДАКТИРОВАТЬ 1 **:

Я изменяю кодовую часть os axios, добавляя withCredentials: true,, как предложено, но получил ошибку: 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.

Итак, я меняю сервер app.js из этого:

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

На это:

(...)
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');

(...)

И получите эту ошибку: 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.

Я думаю, что-то не так сконфигурация сервера ...


РЕДАКТИРОВАТЬ 2:

Это был мой сервер.Нужно использовать Экспресс Корс Написал ответ ниже ...

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Решение проблемы

По какой-то причине, которую я не знаю, моя политика ручного CORS не работает правильно.

//(...)
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 - Я исключаю это и устанавливаю cors yarn add cors --save (или npm install cors --save)
2 - Добавить требование для cors:

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

3 - использовать cors перед моим методом «аутентификации», например:

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

Вот и все. Работает нормально ... наконец-то, спустя почти 2 дня ...

Я фиксирую решение по адресу: https://github.com/dennnisk/cors_police_response_preflight_does_not_have_http_ok

0 голосов
/ 03 января 2019

Вы забыли добавить withCredentials: true в axios?

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

и после этого:

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