Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 在自定义中间件末尾调用next()会导致错误_Node.js_Express_Cookies_Jwt - Fatal编程技术网

Node.js 在自定义中间件末尾调用next()会导致错误

Node.js 在自定义中间件末尾调用next()会导致错误,node.js,express,cookies,jwt,Node.js,Express,Cookies,Jwt,我正在尝试设置viewpages,以便在登录时在页面上显示经过身份验证的用户的信息,如用户名或电子邮件 为此,我使用res.locals函数在全局级别为要访问的页面设置用户数据 const jwt = require("jsonwebtoken") const User = require("../models/User") const checkUser = (req, res, next) => { const token = req.

我正在尝试设置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(),那个么将破坏身份验证中间件的用途。
按如下方式更新代码

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
is有一个异步回调,并且在返回之前正在调用底部的
next()
。因此,您需要将
next()
放入该回调,或者同步使用
jsonwebtoken
。大概是这样的:

const checkUser=(请求、恢复、下一步)=>{
const token=req.cookies.jwt
如果(令牌){
试一试{
const decodedToken=jwt.verify(标记,“公司特殊代码”)
//这仅在令牌解码成功时运行
let user=wait user.findById(decodedToken.id)
res.locals.user=用户
}捕获(错误){
res.locals.user=null//如果用户不存在,则将其设置为null
}
}否则{
res.locals.user=null
}
next();
}
当您使用类似这样的异步回调时,javascript将继续处理脚本的其余部分,同时回调也在运行(或多或少)。因此,调用
next()
时没有意识到需要等待回调或它可能处理的任何事情