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为此场景做了一些事情,我想避免重新发明轮子.
嗯...到目前为止,我所做的是为函数视图创建一个装饰器。装饰器的代码如下:
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。