首页 > 解决方案 > 如何使用 Node、Express、Axios 在 ReactJS 前端设置带有 JWT 令牌的 cookie

问题描述

所以我可以使用邮递员成功地将访问令牌放入 cookie 并且验证工作正常但是在我的前端登录时访问令牌没有进入 cookie

这是在我的路线/Users.js

router.post('/login', async (req, res) => {
    const { username, password } = req.body;

    const user = await Users.findOne({ where: {username: username}});

    if(!user) res.status(400).json({error: `Username does not exist!`});

    bcrypt.compare(password, user.password).then((match) => {
        if(!match) res.status(400).json({error: 'Wrong password!'})

        const accessToken = createTokens(user);

        res.cookie('access-token', accessToken, {
            maxAge: 60*60*24*30*1000, //30 days
            secure: false,
            httpOnly: false
        });

        user.password = undefined;

        res.json(accessToken);
    })
});

控制器/jwt.js

const { sign, verify } = require('jsonwebtoken');

const createTokens = (user) => {
    const accessToken = sign(
        { username: user.username, id: user.user_id }, 
        'e2ereactsecret'
    );
    return accessToken;
};

const validateToken = (req, res, next) => {
    const accessToken = req.cookies['access-token']

    if (!accessToken) 
        return res.status(400).json({error: 'User not authenticated!'})

    try {
         const validToken = verify(accessToken, 'e2ereactsecret')
         if(validToken) {
            req.authenticated = true
            return next();
         }
    } catch(err) {
        return res.status(400).json({error: err})
    }
};

module.exports = { createTokens, validateToken };

这是我的反应前端中的登录功能:

    const login = (e) => {
        e.preventDefault();

        const config = { headers: {"Content-Type":"application/json"}};
        const data = { username: username, password: password };
        axios.post('http://localhost:4000/users/login', data, config).then((res) => {
            console.log(res);
          });
    }

这就是我通过 console.log 得到的,令牌在那里,但它没有进入 cookie。

{data: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZ…DYzfQ.dm1nUa-9z7AQkvirCTM3jrC9a_mx_hsA2waDqQs3cD8", status: 200, statusText: "OK", headers: {…}, config: {…}, …}
config: {url: "http://localhost:4000/users/login", method: "post", data: "{\"username\":\"juan\",\"password\":\"password123\"}", headers: {…}, transformRequest: Array(1), …}
data: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6Imp1YW4iLCJpZCI6MiwiaWF0IjoxNjIzMDM0NDYzfQ.dm1nUa-9z7AQkvirCTM3jrC9a_mx_hsA2waDqQs3cD8"
headers: {content-length: "141", content-type: "application/json; charset=utf-8"}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
status: 200
statusText: "OK"
__proto__: Object

我现在真的很困惑。哈哈。

标签: node.jsreactjsexpressaxiosjwt

解决方案


尝试将httpOnly设置更改为 true。

httpOnly设置意味着无法使用 JavaScript 读取 cookie,但仍可以在 HTTP 请求中将其发送回服务器。如果没有此设置,XSS 攻击可能会使用 document.cookie 来获取存储的 cookie 及其值的列表。


推荐阅读