在自定义中间件末尾调用 next() 会导致错误
Calling next() at the end of custom middleware causes error
我正在尝试设置 viewpages 以在登录时在页面上显示经过身份验证的用户的信息,例如用户名或电子邮件。
为此,我使用 res.locals 函数在全局级别设置用户数据以供页面访问。
const jwt = require("jsonwebtoken")
const User = require("../models/User")
const checkUser = (req, res, next) => {
const token = req.cookies.jwt
if (token) {
jwt.verify(token, "Company_Special_Code", async (err, decodedToken) => {
if (err) {
res.locals.user = null // Set it to null if the user does not exist
next();
} else {
let user = await User.findById(decodedToken.id)
res.locals.user = user
next();
}
})
} else {
res.locals.user = null
next();
}
}
module.exports = {
checkUser
}
第一个代码,每次代码到达端点时调用 next() 函数,允许页面访问用户信息而不会出现任何错误。
但是,如果我只在 checkUser() 函数的最底部调用 next() 函数一次,则会导致错误,声称用户未在视图页面级别定义。代码如下:
const jwt = require("jsonwebtoken")
const User = require("../models/User")
const checkUser = (req, res, next) => {
const token = req.cookies.jwt
if (token) {
jwt.verify(token, "Company_Special_Code", async (err, decodedToken) => {
if (err) {
res.locals.user = null // Set it to null if the user does not exist
} else {
let user = await User.findById(decodedToken.id)
res.locals.user = user
}
})
} else {
res.locals.user = null
}
next();
}
module.exports = {
checkUser
}
如果我正确地编写了函数代码,无论 jwt 令牌的状态如何,或者令牌验证过程中是否出现错误,checkUser() 函数都应该到达底部的 next() 函数。如果您能告诉我我在这里弄错了什么,我将非常感谢您的帮助...
您的验证部分错过了中间件中正确的错误处理。如果令牌无效,那么用户为什么要访问控制器,您可以从中间件本身发送错误。如果您没有从中间件发送错误并调用 next(),那么您的身份验证中间件的目的就会失败。
按如下方式更新您的代码,
const jwt = require("jsonwebtoken")
const User = require("../models/User")
// The routes, which does not requires aurthentication
const usecuredRoutes = []
const checkUser = (req, res, next) => {
if(usecuredRoutes.indexOf(req.path) === -1){
const token = req.cookies.jwt
if (token) {
jwt.verify(token, "Company_Special_Code", async (err, decodedToken) => {
if (err) {
res.locals.user = null // Set it to null if the user does not exist
// Token is invalid, then telll user that he is don't have access to the resource
res.status(403).send('Unauthorized')
} else {
let user = await User.findById(decodedToken.id)
res.locals.user = user
next();
}
})
} else {
// Token does not exists, then telll user that he is don't have access to the resource
res.status(403).send('Unauthorized')
}
} else {
next()
}
}
module.exports = {
checkUser
}
您的 jwt.verify
有一个异步回调,底部的 next()
在 returns 之前被调用。因此,您要么需要将 next()
放入该回调,要么同步使用 jsonwebtoken
。像这样:
const checkUser = (req, res, next) => {
const token = req.cookies.jwt
if (token) {
try {
const decodedToken = jwt.verify(token, "Company_Special_Code")
// This only runs if the token was decoded successfully
let user = await User.findById(decodedToken.id)
res.locals.user = user
} catch (error) {
res.locals.user = null // Set it to null if the user does not exist
}
} else {
res.locals.user = null
}
next();
}
当您使用这样的异步回调时,javascript 将继续处理脚本的其余部分,而该回调 运行 在一边(或多或少)。所以 next()
被调用时没有意识到需要等待回调或它可能处理的任何事情。
我正在尝试设置 viewpages 以在登录时在页面上显示经过身份验证的用户的信息,例如用户名或电子邮件。
为此,我使用 res.locals 函数在全局级别设置用户数据以供页面访问。
const jwt = require("jsonwebtoken")
const User = require("../models/User")
const checkUser = (req, res, next) => {
const token = req.cookies.jwt
if (token) {
jwt.verify(token, "Company_Special_Code", async (err, decodedToken) => {
if (err) {
res.locals.user = null // Set it to null if the user does not exist
next();
} else {
let user = await User.findById(decodedToken.id)
res.locals.user = user
next();
}
})
} else {
res.locals.user = null
next();
}
}
module.exports = {
checkUser
}
第一个代码,每次代码到达端点时调用 next() 函数,允许页面访问用户信息而不会出现任何错误。
但是,如果我只在 checkUser() 函数的最底部调用 next() 函数一次,则会导致错误,声称用户未在视图页面级别定义。代码如下:
const jwt = require("jsonwebtoken")
const User = require("../models/User")
const checkUser = (req, res, next) => {
const token = req.cookies.jwt
if (token) {
jwt.verify(token, "Company_Special_Code", async (err, decodedToken) => {
if (err) {
res.locals.user = null // Set it to null if the user does not exist
} else {
let user = await User.findById(decodedToken.id)
res.locals.user = user
}
})
} else {
res.locals.user = null
}
next();
}
module.exports = {
checkUser
}
如果我正确地编写了函数代码,无论 jwt 令牌的状态如何,或者令牌验证过程中是否出现错误,checkUser() 函数都应该到达底部的 next() 函数。如果您能告诉我我在这里弄错了什么,我将非常感谢您的帮助...
您的验证部分错过了中间件中正确的错误处理。如果令牌无效,那么用户为什么要访问控制器,您可以从中间件本身发送错误。如果您没有从中间件发送错误并调用 next(),那么您的身份验证中间件的目的就会失败。
按如下方式更新您的代码,
const jwt = require("jsonwebtoken")
const User = require("../models/User")
// The routes, which does not requires aurthentication
const usecuredRoutes = []
const checkUser = (req, res, next) => {
if(usecuredRoutes.indexOf(req.path) === -1){
const token = req.cookies.jwt
if (token) {
jwt.verify(token, "Company_Special_Code", async (err, decodedToken) => {
if (err) {
res.locals.user = null // Set it to null if the user does not exist
// Token is invalid, then telll user that he is don't have access to the resource
res.status(403).send('Unauthorized')
} else {
let user = await User.findById(decodedToken.id)
res.locals.user = user
next();
}
})
} else {
// Token does not exists, then telll user that he is don't have access to the resource
res.status(403).send('Unauthorized')
}
} else {
next()
}
}
module.exports = {
checkUser
}
您的 jwt.verify
有一个异步回调,底部的 next()
在 returns 之前被调用。因此,您要么需要将 next()
放入该回调,要么同步使用 jsonwebtoken
。像这样:
const checkUser = (req, res, next) => {
const token = req.cookies.jwt
if (token) {
try {
const decodedToken = jwt.verify(token, "Company_Special_Code")
// This only runs if the token was decoded successfully
let user = await User.findById(decodedToken.id)
res.locals.user = user
} catch (error) {
res.locals.user = null // Set it to null if the user does not exist
}
} else {
res.locals.user = null
}
next();
}
当您使用这样的异步回调时,javascript 将继续处理脚本的其余部分,而该回调 运行 在一边(或多或少)。所以 next()
被调用时没有意识到需要等待回调或它可能处理的任何事情。