如何使用jwt 完成注销(退出登录)功能

原文

1_0wYVCel6fH4L93XmBtY8tA.jpeg

神奇的 JSON Web Tokens(JWT)

JSON Web Tokens (JWT) 是一种无状态处理用户身份验证的方法。 什么意思?
JWT帮助建立认证机制而不将身份验证状态存储在任何存储中,无论是会话内存还是数据库,因此, 当检查用户的身份验证状态时,不需要访问会话内存或执行数据库查询。相反, 根据你选择的用户payload生成token 并在客户端的请求中使用它来标识服务器上的用户 🛂

因此,基本上,每当创建token时,就可以永远使用它,或者直到它过期为止。 JWT生成器可以在生成的时候有一个指定过期时间的选项。

不过你想让已经生成的token失效该怎么办呢?当用户注销或者更改密码的时候你该做些什么呢🤔

注销

通常在使用JWT做身份验证时客户端将token储存在某个地方,并将附加到每个需要身份验证的请求上,所以注销的第一件事就是删除储存在客户端上的token(例如 浏览器本地储存)在这种情况下客户端没有了token请求需要认证的接口自然会得到未认证的响应。不过这就够了吗?这个是防君子不防小人的做法实际上在注销之前通过一些手段将token拿到手在注销后依然可以使用!不信的的话可以自己尝试下。
让我们从后台注销token,你可能会说桥豆麻袋这对于jwt来说并不是那么简单,你并不能像删除cookie和session那样来删除token。

实际上,JWT的目的与session不同,不可能强制删除或失效已经生成的token。

Token 过期

是的 Token 可以设置过期。
在生成token时可以指定过期时间,你可以在有效的paylaod中加上exp字段就像这样:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516234022,
  "exp": 1516239022
}

exp 字段为时间戳,这里的iat字段代表发布时间,此Token设置为在发布后5秒过期⏰。
如果你不想拥有永远有效的Token你应该给你的JWT设置一个合理的到期时间,时间的长短取决于你的应用,我们将在这里使用时长为一天Token,并在登录操作中生成它们,对于NodeJS应用程序,代码应该如下所示:

const jwt = require('jsonwebtoken');
const payload = {
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516234022
}
const token = jwt.sign(payload, 'your-secret', {expiresIn: '1d'})

当这个token过期时验证器会返回一个error,而且后端一旦收到需要授权的请求,就会以未授权的响应状态进行响应。通常,你将从客户端删除令牌并将用户重定向到登录页面。因此,在这个例子中,所有用户在使用你的应用程序1天后将自动注销。

很酷,但我还是想注销!

如前所述,你不能在Token创建后手动使其过期,你实际上不能像使用session那样在服务器端使用JWT注销🙀或者,除非,你可以…
使用JWT应该是无状态的,这意味着你应该将所需的一切存储在payload中,并跳过对每个请求执行DB查询,但是如果你计划有一个严格的注销功能,无法等待Token自动过期,即使你已经从客户端清除了Token,然后你可能需要违背无状态规则并执行一些查询。

有一种实现可能是,存储一个所谓的“黑名单”所有Token是有效的,还没有到期你可以挑选一个拥有TTL功能的数据库,TTL被用于为Token记录Token过期之前剩余的时间量。Redis 是一个很好的选择,这将允许在内存中快速访问列表,然后,在某个中间件中,运行在每个授权请求上,你应该检查提供的令牌是否在黑名单中🕵️‍,如果在的话就抛出一个未认证异常,如果没有让它通过,JWT验证将处理它并确定它是否已过期或仍然有效。

结论

你不能简单地用JWT注销…
似乎,在使用JSON Web令牌时创建干净的注销流程并不那么简单,你应该让Token保持活动状态,直到它自己过期为止;或者,如果你希望在用户注销时限制Token的使用,则选择储存一个Token黑名单。总而言之,只需遵循以下4个要点:

  • 设置令牌的合理过期时间
  • 注销时从客户端删除存储的Token
  • 拥有不再活动Token的数据库,这些Token仍有一些生存时间
  • 针对每个请求根据黑名单查询授权情况
  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
由于 JWT(JSON Web Token)的特性,它是无状态的,服务器不会存储关于 token 的任何信息。因此,JWT注销并不像传统的会话方式那样直接。但是,你可以通过一些方法来实现类似注销的效果: 1. 客户端删除 token:在客户端应用中,当用户发起注销操作时,你可以清除保存在客户端的 token。这样,客户端将不再发送带有注销的 token 的请求,从而实现注销的效果。 2. token 黑名单:你可以使用一个存储机制(例如 Redis 或数据库)来维护一个 token 黑名单。当用户发起注销操作时,将该 token 添加到黑名单中。在服务器端验证 token 时,先检查该 token 是否在黑名单中。如果是,就拒绝访问。 需要注意的是,这种方式需要在服务端对每个请求进行额外的验证,会增加一些开销。 3. token 过期时间:JWT 的一个重要特性是过期时间(exp)。你可以设置合理的过期时间,让 token 在一段时间后自动失效。这样,在 token 过期后,客户端必须重新获取新的 token 才能进行访问。 这种方式可以在一定程度上实现注销效果,但需要权衡 token 过期时间的设置。 无论采用哪种方式,安全性都是关键。你需要遵循最佳实践,例如使用安全的传输方式、适当设置 token 过期时间、处理 token 存储和清除等。 请注意,JWT 是设计为无法撤销的凭证,因此在某些特定场景下,使用传统的会话机制可能更合适。具体取决于你的应用需求和安全要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值