为了账号安全,请及时绑定邮箱和手机立即绑定

未在 cookie 中设置令牌

未在 cookie 中设置令牌

叮当猫咪 2022-06-05 16:16:32
所以我们有一个随机问题,我们存储在 cookie 中用于身份验证的 JWT 令牌时不时地没有在浏览器中设置。现在 99% 的用户进入登录网页输入他们的详细信息,它会向服务器发送一个请求,服务器会发回他们的用户详细信息和设置到 cookie 中的 JWT 令牌。现在时不时地似乎没有设置cookie。现在几乎所有浏览器都发生了随机事件,但没有理由说明原因。它发生在我们的本地、暂存和生产环境中。(出于隐私原因,我删除了一些代码)后端身份验证服务是使用 Node 和 ExpressJS 构建的,它使用以下代码设置令牌:module.exports.signIn = async function(req, res, next) {  try {    const { email, password } = req.body;    if (!email || !password)      throwBadRequest("Please enter a valid email and password");    const data = await Users.get(`?email=${email.toLowerCase().trim()}`);    const { name, val, options } = await Token.generateCookieParams(data);    res.cookie(name, val, options);    return res.json(toDTO(data));  } catch (err) {    next(err)  }};如果有帮助,我们将使用中间件 cookie 解析器。这是设置令牌的代码:async function generateFor(user, expireTime, special = null) {    const payload = { id: user._id, type: user.type, account: user.account };    if (user.entity) {      payload.entity = user.entity;    }    if (special) {      payload.special = special;    }    const token = await jwt.sign(payload, config.secret, {      expiresIn: expireTime    });    return token;  }async function generateCookieParams(user) {    const expireTime = 60 * 60 * 12; // 12 hour    const token = await Token.generateFor(user, expireTime);    return { name: config.tokenKey, val: token, options: { httpOnly: true } };  }我们正在使用中间件 cors 来管理 express 应用程序中的 cors,并将选项凭据设置为 true。然后在前端,我们使用 superagent 从 react 应用程序发出所有请求,我们也使用了 Axios,但有同样的问题。网络的基本代码在前端如下所示:import superagent from "superagent";const superagentManager = {};/** * POST * @param {string} path => the path for the post request * @param {object} data => the object you are posting in json format */superagentManager.post = async (path, data) => {  return await superagent    .post(path)    .withCredentials()    .type("application/json")    .send(data);};如果有人可以帮助我,将不胜感激。系统可以工作,但时不时地假设每 50 次登录中有 1 次没有在浏览器中设置令牌。因此,用户对象是从登录请求返回的,但随后发生的进一步请求会引发错误,因为 cookie 中没有令牌。随着用户群的增长,该错误变得越来越明显。
查看完整描述

2 回答

?
侃侃尔雅

TA贡献1801条经验 获得超16个赞

这看起来像一个 cookie 问题!


因此,有两种方法可以使用 cookie 在浏览器中保持状态。会话数据存储在服务器上,通常使用一些键来检索与用户状态相关的值。Cookies存储在客户端,并在请求中发送以确定用户状态。ExpressJS 支持使用这两者的能力。对于 JWT,您当然想使用 cookie 方法!


让我们先来看看您的 cookie 选项:


// return { name: config.tokenKey, val: token, options: { httpOnly: true } };


const cookieOptions = {

    httpOnly: true

}

到目前为止,这看起来不错。您正在遵循将令牌存储为 http only 的最佳实践,但要正确存储 cookie,您可能需要在 cookie 选项中添加更多内容。


这是 express 文档中 cookie 选项的链接。查看“过期”的描述:


格林威治标准时间 cookie 的到期日期。如果未指定或设置为 0,则 创建会话 cookie。


基本上发生的事情是您没有指定到期时间,因此您的 cookie 被设置为 session cookie。这意味着每当用户关闭浏览器时,cookie 就会被销毁。


奖金:


如果您的网站使用 HTTPS,请确保将 cookie 设置为secure: true


如果它适用于您的团队,您可能还需要检查 sameSite 属性。


查看完整回答
反对 回复 2022-06-05
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

我看不出您的代码有什么问题,但是过去需要注意的一些事情一直困扰着我;

  • 确保您的客户在登录呼叫仍在进行时不会开始下一个呼叫。还要确保正确的错误处理以向客户端显示登录失败。

  • 如果您有代理(如 nginx、haproxy),请确保vary标头配置正确

  • 通过配置和标头确保服务器浏览器中没有发生缓存no-cachemax-age


查看完整回答
反对 回复 2022-06-05
  • 2 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信