首页 > 解决方案 > django-rest-framework 使用 HttpOnly Cookie

问题描述

在以不安全的方式使用djangorestframework-jwt一年多之后,我终于决定让它以更安全的方式工作。

我到处都读过在本地客户端(例如,本地存储)中保存 JWT 令牌不好的地方,最好的解决方案是改用 HttpOnly cookie。

我知道 HttpOnly cookie 确实是一个 cookie,可以保存但不能被浏览器读取。所以我认为它可以像下面这样使用:

我现在正在尝试通过使用 HttpOnly cookie 来使用 djangorestframework-jwt,而 JWT_AUTH_COOKIE 配置似乎是最合适的配置:

如果除了 Authorization 标头之外还想使用 http cookie 作为令牌的有效传输,您可以将 JWT_AUTH_COOKIE 设置为字符串。您在此处设置的字符串将用作请求令牌时将在响应标头中设置的 cookie 名称。如果已设置,令牌验证过程还将查看此 cookie。如果请求中存在标头和 cookie,则“授权”标头优先。

默认为 None 并且在创建令牌时不设置 cookie,在验证它们时也不接受。

在给 JWT_AUTH_COOKIE 一个字符串值之后,我收到了一个 httpOnly cookie,如预期的那样。

问题:

当我调用 refreshToken 时,我得到以下响应:

{"token":["This field is required."]}

没错,我没有在请求的 HEADER 中发送任何令牌,这就是我想要的,因为客户端不应该将它保存在任何地方。

这就是我感到困惑的地方:

如果我从现在开始对客户端对服务器的每个请求都没有错,那么应该将 cookie 添加到请求中。

服务器不应该在看到 Header 中没有传递任何令牌后检查 cookie 吗?如果不是这样,它应该如何工作?

如果有人想为改进做出贡献,还在这里发布了一个 Github 问题:https ://github.com/jpadilla/django-rest-framework-jwt/issues/482

标签: django-rest-frameworkjwt

解决方案


您观察到的问题是正确的,因为尚未使用 cookie 实现刷新令牌 API。

这可能是代码本身的错误。但是没有什么能限制你解决这个问题。

您也可以修补视图以处理基于 cookie 的身份验证。将以下代码添加到您的顶部,urls.py它会处理相同的

from rest_framework_jwt.settings import api_settings

if api_settings.JWT_AUTH_COOKIE:
    from rest_framework_jwt.authentication import JSONWebTokenAuthentication
    from rest_framework_jwt.serializers import RefreshJSONWebTokenSerializer
    from rest_framework_jwt.views import RefreshJSONWebToken

    RefreshJSONWebTokenSerializer._declared_fields.pop('token')

    class RefreshJSONWebTokenSerializerCookieBased(RefreshJSONWebTokenSerializer):
        def validate(self, attrs):
            if 'token' not in attrs:
                if api_settings.JWT_AUTH_COOKIE:
                    attrs['token'] = JSONWebTokenAuthentication().get_jwt_value(self.context['request'])
            return super(RefreshJSONWebTokenSerializerCookieBased, self).validate(attrs)

    RefreshJSONWebToken.serializer_class = RefreshJSONWebTokenSerializerCookieBased

刷新使用 cookie


推荐阅读