代码之家  ›  专栏  ›  技术社区  ›  yierstem

注销Django Rest Framework JWT

  •  1
  • yierstem  · 技术社区  · 7 年前

    我想问一下当我使用JWT时注销是否是个好主意。 为了登录,我发送了一个带有用户名和密码的post请求,以获取所需的令牌(保存到localStorage中),这将允许我向需要该令牌的视图发送进一步的请求。

    所以,我想问我是否应该使用刷新令牌,因为我不能禁用它。

    3 回复  |  直到 6 年前
        1
  •  12
  •   a_k_v    7 年前

    你是对的,即使删除了JWT令牌,它在一段时间内仍然有效,直到它过期。JWT是无状态的。因此,如果要处理注销并使令牌无效,则必须保留数据库或内存缓存以存储无效(黑名单)令牌。然后您需要添加一个新的权限来检查令牌是否被列入黑名单。

    class BlackListedToken(models.Model):
        token = models.CharField(max_length=500)
        user = models.ForeignKey(User, related_name="token_user", on_delete=models.CASCADE)
        timestamp = models.DateTimeField(auto_now=True)
    
        class Meta:
            unique_together = ("token", "user")
    
    
    class IsTokenValid(BasePermission):
        def has_permission(self, request, view):
            user_id = request.user.id            
            is_allowed_user = True
            token = request.auth.decode("utf-8")
            try:
                is_blackListed = BlackListedToken.objects.get(user=user_id, token=token)
                if is_blackListed:
                    is_allowed_user = False
            except BlackListedToken.DoesNotExist:
                is_allowed_user = True
            return is_allowed_user
    

        2
  •  7
  •   Jamil Noyda    6 年前

    JWT是无状态的,这意味着您应该将所需的一切存储在有效负载中,并跳过对每个请求执行DB查询。但是,如果您计划有一个严格的注销功能,即不能等待令牌自动过期,即使您已经从客户端清除了令牌,那么您可能需要忽略无状态逻辑并执行一些查询。那么解决办法是什么呢?

    • 设置令牌的合理过期时间

    • 罪恶黑名单 每一次授权请求

    罪恶黑名单

    所有不再有效且尚未过期的令牌的黑名单。您可以在文档上使用具有TTL选项的DB,该文档将设置为令牌过期前的剩余时间量。

    Redis公司

    黑名单 ,这将允许在内存中快速访问列表。然后,在对每个授权请求运行的某种中间件中,您应该检查所提供的令牌是否在 . 如果是,你应该抛出一个未经授权的错误。如果不是,就让它去,JWT验证将处理它,并确定它是否过期或仍然有效。

    有关详细信息,请参阅 How to log out when using JWT

        3
  •  3
  •   Arghya Saha    7 年前

    但代币仍然有效。

    不知道上面这一行是什么意思,但是您不应该担心在您从localstorage和cookie中清除令牌之后,该令牌是否仍然对用户可用,因为无论哪种方式,它都会在到期日之后失效。