我当前正在使用Express.js提供支持的React前端和Nodejs后端构建应用程序。
我正在使用jsonwebtoken作为安全性方法,并应用名为auth.js
的中间件来授权以/rest
开头的每个端点上的请求,这是auth.js
的代码:
const token = req.header('x-auth-token');
console.log(token); // Get the token from 'x-auth-token' header
if (!token) {
return res.status(400).json({ msg: 'Authorization denied. ' });
}
try {
// validate the token
next();
} catch (e) {
return res.status(401).json({ msg: 'Invalid token. '})
}
以及/rest/*
个端点的路由:
router.all("/", auth, (req, res) => {
// some codes
});
请求
fetch(url + "/rest", {
method: "GET",
mode: "cors",
headers: {
"x-auth-token" : "this is the token" // define the header
"Accept" : "application/json",
"Content-Type" : "application/json",
}
});
router.all()
机制工作正常,我能够使用所有方法访问每个/res
路由。问题是,x-auth-token
中间件中auth.js
头的值始终为“ undefined”。当我将路由更改为route.get()
或route.post()
等时,x-auth-token
的值会正确地从客户端返回令牌。
在此router.all()
方面,我是否缺少一些工作?谢谢大家。
编辑:这是我的cors中间件
module.exports = cors = (req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', {domain});
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type , Accept, x-auth-token');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
}
已解决:
事实证明,x-auth-token
中缺少我的req
标头的原因是由于@Marcos Casagrande提到的Pre-flight request。
现在,我要做的是安装CORS软件包,并在Express documents之后对其进行配置,最后在server.js
文件中包含以下代码段,因为我想要进行cors
配置应用于每个端点:
let cors = require("cors");
let whitelist = [{domains}]
let corsOptions = {
origin: (origin, callback) => {
if (whitelist.indexOf(origin) !== -1 || !origin) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
}
}
app.use(cors(corsOptions));
谢谢大家的帮助。
答案 0 :(得分:1)
使用router.all
时,将需要处理OPTIONS
,并且x-auth-token
在那里将不可用。
当您从浏览器发出请求时,浏览器会首先发出OPTIONS
请求。
如果您输入:
console.log(req.method, req.headers);
您将看到:OPTIONS
和x-auth-token
丢失。正确处理OPTIONS
后,浏览器将发出GET
请求,并在其中显示标题。
因此,您可以自行处理,并在发出CORS请求时设置正确的Access-Control-Allow-Origin
标头,或使用cors
包。
const app = require('express')();
const cors = require('cors');
app.use(cors());
// ...
router.all("/", auth, (req, res) => {
// No OPTIONS here, was already handled by `cors`
});
如果您不发出CORS请求,请在您的auth
中间件中使用它:
if(req.method === 'OPTIONS')
return res.send(); // 200
或先处理选项
router.options('*', (req, res) => res.send());
router.all("/", auth, (req, res) => {
// some codes
});
答案 1 :(得分:0)
我看到您正在尝试从req.header
而不是req.headers
访问标头值,并且您的"Content-Type" : "application/json",
请求中有一个GET
,它将产生一个{{ 1}}仍然要求。
您的客户端应用正在发出跨源请求,您的nodejs服务器必须处理该请求。您可以使用cors来解决这个问题。
您可以在任何自定义标头中发送令牌,但是更好的做法/标准是使用OPTION
标头。