与django和JWT在N分钟后重新登陆

sil*_*gon 5 python django django-authentication django-rest-framework django-rest-framework-jwt

场景:我希望用户在N分钟后传递到安全敏感区域时重新登录,例如当用户即将支付订单时,但是他在1小时前登录,我想确定是他.这通过使用rest_framework_jwt.

详细描述:

我最近一直在测试django 现代Web开发(所以,后端使用rest-api).但是,我遇到了一个问题,我还没有找到解决方案.

rest_framework_jwt您设置身份验证类如下.

'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
Run Code Online (Sandbox Code Playgroud)

这将为一般目的做一项伟大的工作.但是,我希望用户在登录后10分钟进入具有敏感信息的区域时重新识别(重新登录),例如,敏感信息可以是支付区域.因此,我想向Authentication类发送一个参数,告诉用户处于合理的区域.

我认为可能的解决方案,但我不知道该怎么做,是:在使用选项时rest_framework_jwt创建变量.我可以向身份验证类发送一个标志,告诉当前视图是否是敏感区域,如果是这样且用户登录的时间超过10分钟,我可以发送消息说用户需要重新登录才能继续.orig_iatJWT_ALLOW_REFRESH

我不介意分支rest_framework_jwt项目并根据我的目的调整它,但是我想知道如何将参数从视图发送到认证类(在这种情况下:) rest_framework_jwt.authentication.JSONWebTokenAuthentication.

此外,如果已经rest_framework_jwt为此场景做了一些事情,我想避免重新发明轮子.

sil*_*gon 0

嗯...到目前为止,我所做的是为函数视图创建一个装饰器。装饰器的代码如下:

from functools import wraps
from rest_framework_jwt.settings import api_settings
from django.utils.translation import ugettext as _
from calendar import timegm
import datetime
jwt_decode_handler = api_settings.JWT_DECODE_HANDLER
def recently_authenticated():
    def decorator(func):
        @wraps(func)
        def inner(request, *args, **kwargs):
            jwt_payload = jwt_decode_handler(request._auth)
            rencent_auth_limit = api_settings.JWT_RECENT_AUTHENTICATION_DELTA
            if isinstance(rencent_auth_limit, datetime.timedelta):
                rencent_auth_limit = (rencent_auth_limit.days * 24 * 3600 +
                                 rencent_auth_limit.seconds) + jwt_payload["orig_iat"]
            timenow = timegm(datetime.datetime.utcnow().utctimetuple())
            if timenow>rencent_auth_limit:
                return Response({"detail":_("you have to reidentify to enter this area")},
                                status=401)
            return func(request, *args, **kwargs)
        return inner
    return decorator
Run Code Online (Sandbox Code Playgroud)

响应格式以与 相同的格式给出rest_framework_jwt.authentication.JSONWebTokenAuthentication。该常量是插入到包(fork)JWT_RECENT_AUTHENTICATION_DELTA中的临时参数。settings.pyrest_framework_jwt

最后,为了使用它,可以将装饰器添加到任何视图。例如:

@api_view()
@recently_authenticated()
def index_view(request):
    data = User.objects.filter()
    return Response(UserSerializer(data, many=True).data)
Run Code Online (Sandbox Code Playgroud)

当用户不久前通过身份验证时,它会发送{"detail":"you have to reidentify to enter this area"}带有代码的消息401。这可以由前端评估和解析,并将用户重定向到登录。

注意:装饰器只评估时间和经过的时间。判断是否是正确用户和正确令牌的验证仍然由 执行rest_framework_jwt.authentication.JSONWebTokenAuthentication