首页 > 解决方案 > 使用 bcrypt 和 jwt 的身份验证不起作用

问题描述

我对 Node.js / Express 和 Web 应用程序的开发非常陌生。我尝试做一个简单的用户注册,在将哈希保存到 mongodb 之前,我使用 bcrypt 对密码进行哈希处理。应该允许用户登录的登录表单随后会在数据库中查找用户,然后比较两个密码。

我确实想保护我的网络应用程序中的某些路由,以便只有经过身份验证的用户才能访问它们。因此,当成功登录时,我确实沿响应标头发送了一个 Json Web 令牌(jwt),然后应该使用该响应标头 - 当重定向到受保护的“/大厅”路由时 - 对用户进行身份验证并允许他/她继续该路由.

但是,我总是收到以下错误:

错误 [ERR_HTTP_HEADERS_SENT]:在将标头发送到客户端后无法设置标头

所以看起来它在尝试设置标头之前已经向客户端发回了响应,这当然不再可能了。

我非常感谢您的帮助!

我确实使用以下代码:

注册功能

async function register(req, res) {
    //Check with user already exists
    const  emailExists = await User.findOne({email: req.body.email});
    if(emailExists) {
        return res.status(400).send('User already exists!');
    };
    //Hash the password and create new user from request data
    bcrypt.hash(req.body.password, 10, async function (err, hashedPass){
        if(err){
            res.json({
                error: err
            });
        }
        let user = new User({
            name: req.body.name,
            email: req.body.email,
            username: req.body.username,
            password: hashedPass,
            password2: hashedPass
        });
        try {
            await user.save();
        }catch (err) {
            res.status(400).send(err);
        };
    });
    res.render('index');
};

登录功能

async function login(req, res) {
    const user = await User.findOne({email: req.body.email});
    if(!user) {
        return res.status(400).json({message: 'User not found!'}).render('index');
    };
    bcrypt.compare(req.body.password, user.password).then((result)=> {
        if(result){
            const token = jwt.sign({_id: user._id}, process.env.TOKEN_SECRET);
            res.setHeader('auth-token', token.toString());
            res.redirect('/lobby');
        }else {
            return res.status(400).json({message: 'Passwords do not match!'}).render('index');
        }
    }).catch((err)=> {
        console.log(err);
    });
};

作为'/lobby' 路由的中间件(即当有人向'/lobby' 发出get 请求时),我使用了一个“verifyToken”函数,它应该确保通过jwt 对用户进行正确的身份验证。

验证令牌函数

const jwt = require('jsonwebtoken');

module.exports = function(req, res, next) {
    console.log('verify function started');
    const token = req.header('auth-token');
    console.log(token);
    if(!token) {
        res.status(401).json({
            message: 'Access denied!'
        });
    };
    try {
        const verified = jwt.verify(token, process.env.TOKEN_SECRET);
        req.user = verified;
        next();
    }catch (err) {
        res.status(400).json({
            message: 'Invalid token!'
        });
    };
};

如前所述,我将非常感谢您的帮助!我认为问题比我想象的要简单得多:-)。

干杯

标签: node.jsexpressjwtbcrypt

解决方案


看起来像在登录函数中设置了标题。我可以通过console.log(res.header('auth-token'));. 随后重定向到“/lobby”被调用,因为verifyToken 函数确实启动了。

但是,在verifyToken 函数中,相应的标头是 then undefined。因为我也经常收到'Access denied!'消息。

如前所述,在对 /lobby 路由执行 get 请求时,我确实将 verifyToken 函数称为中间件。'/lobby' 的路线如下所示:

const express = require('express');
const router = express.Router();
const lobbyCtrl = require('../controllers/lobby');
const verify = require('./verifyToken');

router.get('/', verify, lobbyCtrl.display);

module.exports = router;

推荐阅读