如何在授权标头中将带有 fetch 和 cors 的 JWT 令牌发送到 Express 服务器?

Posted

技术标签:

【中文标题】如何在授权标头中将带有 fetch 和 cors 的 JWT 令牌发送到 Express 服务器?【英文标题】:How to send JWT token with fetch and cors to an Express server in Authorization headers? 【发布时间】:2018-06-01 09:39:16 【问题描述】:

我可以从 localStorage 中检索 JWT 令牌并将其发送到 req.body,但由于某种原因,我无法使用 headers.Authorization 中的 fetch() 将其发送到服务器。我可以在客户端记录令牌,但在服务器上没有收到它。

客户端:React,Redux-Saga。

function* getInitialStateFetch()

  var actionType = 'GET_INITIALSTATE_REDUCER';
  var path = 'react/listings28';

  var token = localStorage.getItem('my_tkn');
  console.log(token) // logs token

  var httpHeaders;

  if(token)
  httpHeaders =  
    'Content-Type' : 'application/x-www-form-urlencoded', 
    'Accept' : 'application/json',
    'Authorization' : `Bearer $token`
  ;
   else 
    httpHeaders =  
      'Content-Type' : 'application/x-www-form-urlencoded', 
      'Accept' : 'application/json'
    ;
  

  let options = 
    method: 'GET',
    mode: 'no-cors',
    headers: new Headers(httpHeaders),
    credentials: 'same-origin'
  ;

  yield call(apiCall, path, options, actionType);

apiCall.js

export default function* apiCall(path, options, actionType)

  try 
    const response = yield call(fetch, `http://blah/$path`, options);
    const data = yield call([response, response.json]);

    // call reducer
    yield put(type: actionType, payload: data);
   catch (e) 
    console.log(e.message);
    console.log(`error api call for $actionType`);
  

服务器:快递。

router.get('/react/listings28', parserFalse, (req, res)=>


  res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3333');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
  res.setHeader('Access-Control-Allow-Credentials', true);

  var token = req.headers.Authorization; // nothing here

  console.log(`req headers below`);
  console.log(req.headers); // no Authorization here

req.headers 来自服务器的截图

【问题讨论】:

删除mode: 'no-cors'。指定mode: 'no-cors' 的效果之一是它告诉您的浏览器阻止您的前端javascript 代码向请求中添加除AcceptAccept-LanguageContent-LanguageContent-Type 之外的任何标头,其值为@ 987654335@、multipart/form-datatext/plain。在***.com/questions/42506376/…查看答案 我尝试过不使用 no-cors。仍然没有授权,它不会发送cookie。 其实还是会发送 cookie 和关闭模式 no-cors 没有区别 【参考方案1】:

终于明白了。切入正题 - 它不起作用,因为浏览器发送 Authorization 标头它需要有 mode: 'no-cors' 但是如果你删除 mode: no-cors 那么 fetch() 甚至不会尝试从本地主机发送请求但是如果我将 bundle.js 上传到服务器,它将正常工作。此外,如果要发送 cookie,还需要将凭据设置为同源,默认情况下 fetch() 凭据设置为省略。

因此,解决方法是使用 webpack 的开发代理,这样您就可以使用服务器而不是 localhost。

【讨论】:

以上是关于如何在授权标头中将带有 fetch 和 cors 的 JWT 令牌发送到 Express 服务器?的主要内容,如果未能解决你的问题,请参考以下文章

使用带有模式的 fetch API:'no-cors',无法设置请求标头

带有授权标头的 AngularJS CORS

CORS,防止带有授权标头的请求预检

如何 CORS 允许 Sails 中的标头

如何在 Spring Boot 2.x 中将 CORS 添加到 oauth2/resource 服务器?

CORS:响应中缺少授权标头(jQuery / Spring)