jwt - 在 Vue.js 中存储令牌的位置?

时间:2021-05-16 08:03:00

标签: vue.js jwt authorization vuex

我在一些安全博客中读到在 localstorage 中存储令牌是不安全的,所以我想要做的是将令牌存储在 vuex 存储中,并且所有 api 调用都将在所有后续请求中包含该令牌。

但是我第一次登录成功时无法访问到token,我想做的是第一次把token存到vuex存储中,想到把token发送到body中响应,但这将是一种易受攻击的方法,因此我将其发送到标头 ["authorization"] 中。

下面分别是我的 user.js 和 login.vue 文件。

router.post('/login', function (req, res, next) {
    const {
        UserName,
        Password
    } = req.body;

    if (UserName.length == 0 || Password.length == 0) {
        res.status(400).json({
            message: 'Email or Password is empty',
        });
    } else {
        login_pool.query(
            'SELECT * FROM authentication WHERE user_name = ($1) and password = crypt(($2), password)',
            [UserName, Password],
            (err, results) => {
                if (err) {
                    throw err;
                } else if (results.rows.length == 1) {
                    // On Successful Login
                    const token = jwt.sign(
                        {
                            user_name: results.rows[0].user_name,
                            full_name: results.rows[0].full_name,
                            phone_number: results.rows[0].phone_number,
                        },
                        btoa(process.env.TOKEN_SECRET), // converting token_secret to base 64
                        { expiresIn: '1800s' },
                        { algorithm: 'HS256' },
                        (err) => {
                            if (err) {
                                res.status(400).json({
                                    message: 'Not able to create a token',
                                });
                                console.log(err);
                            }
                        }
                    );
                    res.header('Authorization', `Bearer ${token}`);
                    res.status(201).json({
                        message: results.rows[0].full_name + 'logged in.',
                    });
                    console.log(results.rows[0].full_name + 'Just Logged In. ');
                } else {
                    login_pool.query(
                        'SELECT * FROM authentication WHERE user_name = ($1)',
                        [UserName],
                        (errUser, resultUser) => {
                            if (resultUser.rows.length != 1) {
                                res.status(400).json({
                                    message: 'User with this email does not exist',
                                });
                            } else {
                                res.status(400).json({
                                    message: 'Password is not correct',
                                });
                            }
                        }
                    );
                }
            }
        );
    }
});
LoginSubmit() {
    this.axios
        .post(
            "http://127.0.0.1:3000/users/login",
            {
                UserName: this.UserName,
                Password: this.Password,
            },
            {
                headers: {
                    "Content-Type": "application/json;charset=UTF-8",
                    "Access-Control-Allow-Origin": "*",
                    Accept: "application/vnd.api+json",
                },
            }
        )
        .then(
            (res) => {
                // successful login
                console.log(res.headers); // authentication header not present here
                this.Error = "";
                console.log(this.axios.defaults.headers.common); // authentication header not present here
            },
            (err) => {
                console.log(err.response.data.message);
                this.Error = err.response.data.message.replace(/"/g, "");
            }
        );
},

2 个答案:

答案 0 :(得分:1)

我从来没有见过这样的事情。 JWT 可以作为响应正文的一部分发送到某个 POST /auth 端点。然后,您可以使用某种存储方式保存该令牌。

到底是 localStorage 还是 cookie 是有争议的;我个人只是使​​用 localStorage 以便 API 尽可能无状态。但是,在使用 cookie 时,您可以为 cookie 设置某种过期时间,以确保其在过期日期后被删除。

Vuex store 本质上是一个全局状态对象,一旦您刷新浏览器窗口,它就会丢失所有内容。除非你将它与某种加载/保存到你的 Vuex 商店的 localStorage/sessionStorage 结合起来。

因此,我建议您删除 Access-Control-Expose-Headers: Authorization 标头,并在身份验证期间将 JWT 令牌作为 POST 正文响应发送。此类身份验证请求的安全性取决于您使用的是 http 还是 https。显然,您总是想使用 https,因为 (wifi-) 网络的某个恶意所有者可以轻松地以纯文本形式读取所有不使用的内容。

答案 1 :(得分:0)

res.header({
   Authorization: "Bearer" + token,
   "Access-Control-Expose-Headers": "Authorization",
});

使用 Access-Control-Expose-Headers 解决了我的问题,现在我可以使用 res.headers["authorization"]

访问前端部分的 Authorization Header