lor*_*ock 5 python django django-rest-framework
您好,我一直在使用 Django Rest Framework 和 JWT 作为身份验证框架,我成功地基于电子邮件 OTP 进行了双因素身份验证登录,但我想要改进的一件事是我想改进登录并保存用户的设备,以便重复 2FA(双因素身份验证)可以最小化吗?
这是我为在用户电子邮件上发送 otp 所做的某些代码实例。
序列化器.py
class UserLoginSerializer(serializers.Serializer):
email = serializers.EmailField()
password = PasswordField()
Run Code Online (Sandbox Code Playgroud)
视图.py
class UserLoginView(generics.CreateWithMessageAPIView):
"""
Use this end-point to get login for user
"""
message = _('Please check your email for 6 digit OTP code.')
serializer_class = serializers.UserLoginSerializer
def perform_create(self, serializer):
usecases.UserLoginWithOTPUseCase(self.request, serializer=serializer).execute()
Run Code Online (Sandbox Code Playgroud)
用例.py
class UserLoginWithOTPUseCase(CreateUseCase, OTPMixin):
def __init__(self, request, serializer):
self._request = request
super().__init__(serializer)
def execute(self):
self._factory()
def _factory(self):
credentials = {
'username': self._data['email'],
'password': self._data['password']
}
self._user = authenticate(self._request, **credentials)
if self._user is not None:
"""
Sends email confirmation mail to the user's email
:return: None
"""
code = self._generate_totp(
user=self._user,
purpose='2FA',
interval=180
)
EmailVerificationEmail(
context={
'code': code,
'uuid': self._user.id
}
).send(to=[self._user.email])
else:
raise PermissionDenied(
{
'authentication_error': _('User name or password not matched')
}
)
Run Code Online (Sandbox Code Playgroud)
我很困惑如何允许或保存设备以防止重复 2FA。
在非常高的层面上:对 OTP 进行标记(将 替换为otp)JWT。
AJWT无非是带有一些标准化字段(过期)、(不在之前)等的JSON 签名有效负载。签名(对称或非对称)确保完整性、真实性和不可否认性(例如,令牌是由我们认为的人发行的并且未被更改)。expnbf
在JWT有效负载中,您可以放置任何内容(请记住该值未加密),包括应用程序逻辑所需的数据。您还可以在不同的身份验证步骤中交换不同的内容JWT。
<username, password>是否有效,type_1_jwt如果启用了 2FA,它会收到一个,否则会收到一个type_2_jwt<type_1_jwt, otp>如果两者都有效它会收到一个type_2_jwttype_2_jwt您的应用程序仅在所有其他端点上接受在这里,您可以在初始用户身份验证后(或者即使检测到可疑设备)灵活地请求 OTP。如果需要 OTP,则用户不需要再次插入密码,而且密码也不会存储在任何地方,也不会在任何未来的请求中重新提交。<username, password, otp>安全级别与同步身份验证保持相同
renew_jwt(很长一段时间后过期或永远不会)renew_jwta auth_jwt(快过期)auth_jwt您的应用程序仅在所有其他端点上接受如果您希望撤销或更改身份验证(更改角色),此解决方案可提供极大的灵活性。您可以auth_jwt在整个应用程序中使用它,但过期速度非常快,然后您就拥有了一个renew_jwt已经用于正确身份验证的交易,并且可以用于自动请求auth_jwt,只有满足某些条件,系统才会满足此请求(例如身份验证尚未撤销)。
<username, password, otp>它收到一个auth_jwt(或一个renew_jwt)和一个otp_jwt。<username, password, otp_jwt>auth_jwt您的应用程序仅在所有其他端点上接受第一次身份验证后,用户设备会收到一个otp_jwt(具有任意长的持续时间)并可以存储在设备上(cookie、appStorage、secureStorage...)。这otp_jwt可以在将来的任何时刻使用(与用户名和密码一起)再次进行身份验证。
从概念上讲otp_jwt,令牌是用户过去已成功使用 OTP 进行身份验证的安全证明
假设设备被认为相当安全,这种策略不会显着增加未经授权访问的风险。但请记住,您应该始终为用户提供一个选项,例如completely log out也可以清除此令牌。