【发布时间】:2019-04-19 12:00:28
【问题描述】:
我想我在写它的过程中已经解决了这个问题,基本上解决方案似乎是:
将静态文件处理程序移到另一个 use() 实例之上
确认这是一种可接受的方法将不胜感激,并且可能会在类似情况下帮助其他人。
期望的行为
将use() 实例应用于所有路由,但由以下人员处理的路由除外:
app.use(express.static("dist"));
实际行为
use() 正在应用于所有路由,包括由以下人员处理的路由:
app.use(express.static("dist"));
场景
为了保护对 API 的访问,我使用的是 Lynda.com 教程中描述的模型:
Node.js: Securing RESTful APIs
在伪代码中,模型主要由以下部分组成:
- 一个全局
use()实例,用于检查是否已发送 jwt 令牌 - 如果令牌已发送,则验证令牌
- 如果验证失败或未发送令牌,它会将
req.user属性设置为undefined - 否则,如果验证成功,它将
req.user属性设置为解码的 jwt 值 - 后续中间件根据
req.user的值执行条件行为
此模型适用于所有意图和目的。
但是,我最近添加了一些控制台日志记录,并且可以看到正在为两者执行验证:
- api 请求(期望的行为)
- 通过
app.use(express.static("dist"))per this convention 提供的静态文件(不良行为)
问题
如何将验证use() 实例应用于所有路由,app.use(express.static("dist")) 处理的路由除外。
我的尝试
我想我已经通过将2 部分移至1 部分上方的代码部分解决了这个问题。
// 01. verification use() called on all requests
app.use((req, res, next) => {
// if jwt authorisation has been sent in headers, verify it
if (req.headers && req.headers.authorization && req.headers.authorization.split(' ')[0] === 'JWT') {
console.log("jwt verification sent, verifying...");
try {
// this is synchronous as it has no callback
req.user = jsonwebtoken.verify(req.headers.authorization.split(' ')[1], 'RESTFULAPIs');
console.log("jwt verified, will return decoded value");
} catch (err) {
req.user = undefined;
console.log("jwt verification failed, user will remain undefined: " + err);
}
// move to the next piece of middleware
next();
}
// if jwt authorisation has not been sent in headers
else {
console.log("jwt verification not sent, leaving user as undefined");
console.log(req.originalUrl);
req.user = undefined;
// move to the next piece of middleware
next();
}
});
// 02. use() for serving static files
app.use(express.static("dist"));
// 03. middleware to check if login has been verified
const api_login_required = (req, res, next) => {
// if token verification was successful and the user property exists
if (req.user) {
// move to the next piece of middleware
next();
}
// otherwise, return unauthorised user message
else {
res.json({ verification: 0 });
}
}
// 04. middleware called in route handlers
app.route("/api/:api_version/users/private_data")
.get(api_login_required, api_users_private_data_get)
.post(api_login_required, api_users_private_data_post);
【问题讨论】: