在时间到期时注销用户

Logging user out on time expiry

我正在开发一个 nodejs(express) 服务器和一个使用 API 的反应 FE。服务器令牌存储令牌和秘密。当用户退出 FE 时,秘密会被刷新。 (原始开发人员使用自定义身份验证而不是 JWT..) 问题是,如果用户不按注销按钮,他们可以无限期地登录。就解决方案而言,我有一个想法,服务器可以以某种方式监视来自客户端的最后一个请求,当 30 分钟过去后,服务器可以更新秘密 - 我手动尝试过这个并且当客户端刷新时 api 调用失败。我可以在 FE 中构建一些额外的逻辑,捕获向用户显示注销消息的错误,然后删除本地存储。 此外,客户端可以从最后一次 api 调用算起 25 分钟,并在注销用户之前显示带有倒计时的对话框。

也许,我把这个复杂化了,还有另一种方法 - 当前使用本地存储,但不确定我是否要使用 cookie,它会解决浏览器不活动或浏览器关闭时自动注销的问题,如果它是可以在 cookie 过期之前进行对话倒计时(如果用户 select 保持会话打开,它会被更新)

如果有可行的选择,将不胜感激。

代码:

api/createCustomer

schemaObj.customerToken = crypto.createHash('sha1').update(uuidv4()).update(config.hidden.salt).digest('hex');
schemaObj.customerSecret = crypto.createHash('sha256').update(uuidv4()).update(config.hidden.secret).digest('hex');
schemaObj.password = bcrypt.hashSync(password, bcrypt.genSaltSync(10));


api/login

var loginValid = bcrypt.compareSync(password, bidder.password);
....
res.apiSuccess(customer);

反应代码:

axios.post('/api/login', formData)
let { customerToken, customerSecret, isVerified } = res.data.data;
.....

localStorage.setItem("customerData", JSON.stringify({ customerToken, customerSecret }));

也许像

setTimeout(function(){ req.session.destroy(); }, milliseconds_since_page_loaded);

或使用req.session.destroy();最适合的地方。我不确定我是否完全理解你想超时的时间。

也许你可以将一个变量设置为自上次调用以来的时间,然后每分钟给它 ++,然后添加到任何执行调用以重置它的函数,并且每 30 minutes/however 长它检查那个变量。

如果您想在登录时过期,您必须在某处保存时间戳 属性 以进行检查。大多数标准身份验证系统都有此功能,例如JWT 有 exp 声明,cookie 有 max-age。

对于您所描述的自定义系统,您需要自己进行跟踪。

据我了解系统

  • customerToken = 客户的 id
  • customerPassword = 登录密码
  • customerSecret = 随所有请求发送到服务器的实际令牌。

因此服务器接收到 customerSecret,它有一个中间人根据数据库检查该秘密以检查是否应该允许用户继续。

你几乎没有选择

将列登录时间添加到您的用户表。

  • 当用户登录时,然后用当前时间戳更新该字段。
  • 在数据库中查找机密时,检查登录时间戳是否在 30 分钟内。

使用 cookie

  • 当用户登录时将秘密添加到 cookie。
  • 在 React 应用程序中使用 withCredentials 将 cookie 发送到服务器
  • 中间是检查 cookie 而不是查看数据库

将secret移动到redis

  • 当用户登录时,将secret添加到redis并过期属性。
  • 从 react as Bearer 发送秘密
  • 中间在redis中查找secret来查看用户。

认证和授权的整体要点:

  • 根据每个请求读取完整的事务数据库非常昂贵。
  • 会话状态可以容忍数据丢失,即使丢失也没关系,您可以随时recreate/restore它。
  • 你永远不应该在 localStorage 中存储秘密或令牌,因为它在客户端上,因此可以被其他应用程序访问。