JWT和Express的使用报错显示:令牌验证失败

第一点:出现令牌验证失败,是因为设置了错误处理中间件,这是正常的。

app.use((err, req, res, next) => {

    // token校验不通过提示

    if (err.name === "UnauthorizedError") {

        console.log("token已失效,重新登录",err);

        return res.send(Response.error("token已失效,重新登录", states.AUTH_ERROR))

    }

    // 打印异常

    console.log("异常信息:", err);

    // 设置http响应的状态码,响应到前端

    res.send(Response.error("服务器异常,重新访问", 500))

    next()

})

 

 第二:翻阅很多CSDN资料,都只是在教人生成token和配置unless排除列表,难道没人教路由怎么通过JWT验证?这是我这个bug产生的重要原因。

app.use(expressJWT({ credentialsRequired: false,secret: secretKey, algorithms: ["HS256"] }).unless({

    path: [

        // "/userinfo/get",

        "/userinfo/insert",

        "/userinfo/login",

        // "/userinfo/get",

    ]

}))

 

 第三:其中还有一个原因:生成token时没有使用正确的格式,正确的格式应该在密钥之前加上      'Bearer ' + 密钥。(血泪教训),如果不加'bearer ',jwt会直接验证失败,注意bearer后面有空格,

function generateToken(d_admin) {

    // 生成token使用jwt的sign方法

    return 'Bearer ' + jwt.sign({username : d_admin}, secretKey, { expiresIn })

}

 第四:最关键一点,第二点的代码似乎是在配置拦截规则,所以基本上所有的路由都会被拦截(除了unless中的排除路由),此处有点不懂。既然被拦截,那么如何才能让需要验证的路由通过JWT的验证了?

首先,需要配置好路由验证中间件。此处的验证方法调用了我的其他js文件。

const haveToken = (req, res, next) => {
    console.log('中间件执行' + req.headers.authorization)
    const token = req.headers.authorization
    const tokenstr = token.split(' ')[1];
    if (token) {
        const decode = verifyToken(tokenstr)
        if (decode) {
            req.user = decode
            next()
        } else {
            res.send({
                code: 401,
                msg: 'token已过期'
            })
        }
    }
}

 其他js代码文件。

/**
 * 使用jwt管理token
 */
// 导入jsonwebtoken,生成jwt字符串的模块
const jwt = require("jsonwebtoken")
// 获取密钥
const { secretKey, expiresIn } = require("./config.js")
/**
 * 生成token
 * @param {String} uid 
 * @param {Number} scope 
 * @returns 
 */
function generateToken(d_admin) {
    // 生成token使用jwt的sign方法
    return 'Bearer ' + jwt.sign({username : d_admin}, secretKey, { expiresIn })
}

function verifyToken(token) {
    try {
        // token认证,使用jwt的verify方法
        return jwt.verify(token, secretKey)
    } catch (e) {
        return false
    }
}

module.exports = { generateToken, verifyToken }

最后,需要在我们需要验证的路由身上加上这个中间件!

router.get("/userinfo/get", haveToken,(req, res) => {
    // console.log(req.auth)
    // console.log('拿到的数据' + req.body)
    console.log('数据',req.headers.authorization)
    const token = req.auth
    res.send({
        code: '200',
        data: '前端'
    })
})

应该完成了,有些地方不是很理解到位希望大佬指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值