【问题标题】:node.js cannot find 'auth_token' in cookies. Keeps throwing TypeErrornode.js 在 cookie 中找不到“auth_token”。不断抛出 TypeError
【发布时间】:2021-11-19 03:40:26
【问题描述】:

我正在尝试在访问静态页面之前验证用户是否拥有 Json Web 令牌。下面是我必须这样做的代码。我的问题是我无法在浏览器 cookie 中找到 JWT。我最终得到一个 TypeError,你会在这篇文章的底部找到。我知道我的代码可以正常工作,因为我可以使用邮递员手动将 jwt 令牌添加到标头中并且可以正常工作。

verifyToken.js

const jwt = require('jsonwebtoken');

module.exports = function(req,res,next){
        const token = req.cookies.auth_token;
        if (!token) {
            return res.status(403).send('Access Denied');
        }
        try{
            const verified = jwt.verify(token, process.env.TOKEN_SECRET);
            req.user = verified;
            return next();
        } catch (err) {
            res.clearCookie('token');
            res.status(403).send('Invalid Token');
        }
    };

auth.js

const router = require('express').Router();
const User = require('../model/User');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const {registerValidation, loginValidation} = require('../validation');
const { redirect } = require('express/lib/response');

//Register New User
router.post('/register', async (req,res) => {

    //Validate the data before creating user
    const {error} = registerValidation(req.body);
    if (error) return res.status(400).send(error.details[0].message);

    //Checking if user already exist in database
    const emailExist = await User.findOne({email: req.body.email});
    if(emailExist) return res.status(400).send('Email already exists');

    //Hash the password for secruity
    const salt = await bcrypt.genSalt(10);
    const hashedPassword = await bcrypt.hash(req.body.password, salt);

    //Create a new user
    const user = new User({
        name: req.body.name,
        email: req.body.email,
        password: hashedPassword
    });
    res.redirect('/login')
    try{
        const savedUser = await user.save();
        res.send({user: user._id});
    }catch(err){
        res.status(400).send(err);
    }
});

//Login
router.post('/login', async (req,res) => {
    const {error} = loginValidation(req.body);
    if (error) return res.status(400).send(error.details[0].message);

    //Checking if eamil exist in database
    const user = await User.findOne({email: req.body.email});
    if(!user) return res.status(400).send('Email or password does not exists');

    //Check if password is correct
    const validPass= await bcrypt.compare(req.body.password, user.password);
    if(!validPass) return res.status(400).send('Invalid password')
    
    //Creat and assign json web token
    const token = jwt.sign({_id: user._id}, process.env.TOKEN_SECRET);

 res.cookie('auth_token', token, {
        httpOnly: true,
        // secure: false,
        // maxAge: 1000000,
        // signed: true,
    })
    //res.header('auth-token', token);
    //Redirects you to welcome page after successful login
    res.redirect('/welcome');
});

module.exports = router;

TypeError:无法读取未定义的属性“auth_token” 在 module.exports (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\routes\verifyToken.js:4:35) 在 Layer.handle [as handle_request] (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\layer.js:95:5) 在下一个(D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\route.js:137:13) 在 Route.dispatch (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\route.js:112:3) 在 Layer.handle [as handle_request] (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\layer.js:95:5) 在 D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\index.js:281:22 在 Function.process_params (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\index.js:335:12) 在下一个(D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\index.js:275:10) 在 urlencodedParser (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\body-parser\lib\types\urlencoded.js:91:7) 在 Layer.handle [as handle_request] (D:\coding-stuff\Web Dev\Node.js\Node.js_Authenticator\node_modules\express\lib\router\layer.js:95:5)

编辑:

const jwt = require('jsonwebtoken');
const router = require('express')();
const cookieParser = require('cookie-parser');
router.use(cookieParser());
module.exports = function(req,res,next){
        const token = req.header('Cookie');
        if (!token) {
            return res.status(403).send('Access Denied');
        }
        try{
            const verified = req.header('Cookie');
            req.user = verified;
            // const verified = jwt.verify(token, process.env.TOKEN_SECRET);
            // req.user = verified;
             next();
        } catch (err) {
            res.clearHeader;
            res.status(403).send('Invalid Token');
        }
    };

此代码的唯一问题是它仅检查响应标头中是否存在 cookie,而不是该 cookie 是否包含有效的 JWT。我现在的问题是如何使这段代码更具体地寻找有效的 JWT?

【问题讨论】:

  • 你在其他路由器之前使用 router.use(express.cookieParser()) 吗?
  • 确保已导入 const express = require('express')
  • @AmanurRahman 不,我没有在任何其他路由器之前使用 router.use(express.cookieParser()) 。我也进口了快递。

标签: javascript node.js express cookies jwt


【解决方案1】:

您需要使用cookie-parser

const router = require('express')();
const cookieParser = require('cookie-parser')
const User = require('../model/User');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
const {registerValidation, loginValidation} = require('../validation');
const { redirect } = require('express/lib/response');

router.use(cookieParser())
...

要使 .cookies 可用,假设您使用的是节点 14.x,也可能值得使用可选链接

例如

const token = req?.cookies?.auth_token;

【讨论】:

  • 这修复了我的 TypeError 但我不认为它实际上是在我的 cookie 中寻找 auth_token 因为当我像以前那样使用 PostMan 时它不再起作用我只是被拒绝访问,这意味着有! cookie 中的标记。即使我在浏览器中查看时也有。
  • 嘿@AlexanderMurdock 如果没有完整的源代码,真的很难给你一个更好的答案,看起来你有很多活动部件,所以我在这里创建了一个工作示例:github.com/JamesMahy/SO-69338984-cookie-jwt-problem 有也是您可以使用的自述文件中的公共邮递员集合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 1970-01-01
相关资源
最近更新 更多