python - 使用 Django REST 进行两因素身份验证的端点
问题描述
我正在创建一个 api,用于在登录时使用两因素身份验证对用户进行身份验证。
登录成功后重定向到以下视图。
class TOTPView(APIView):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.verified = False
self.last_verified_counter = -1
self.totp = self.generate_totp()
def get(self, request, *args, **kwargs):
logger.debug(self.totp)
return Response({'success': True},
status=status.HTTP_201_CREATED)
def post(self, request):
token = int(request.data.get('totp_token'))
# check if the current counter value is higher than the value of
# last verified counter and check if entered token is correct by
# calling totp.verify_token()
if ((self.totp.t() > self.last_verified_counter) and
(self.totp.verify(token))):
# if the condition is true, set the last verified counter value
# to current counter value, and return True
self.last_verified_counter = self.totp.t()
self.verified = True
return Response({'success': True},
status=status.HTTP_404_NOT_FOUND)
else:
# if the token entered was invalid or if the counter value
# was less than last verified counter, then return False
self.verified = False
return Response(status=status.HTTP_404_NOT_FOUND)
def generate_totp(self):
key = random_hex(20)
totp = TOTP(key)
totp.time = time.time()
return totp
在这里,当用户发布 OTP 代码/令牌时,POST 方法会调用并通过再次调用self.totp
来覆盖其值。self.generate_totp()
这永远不会验证 TOTP。我在这里做错了吗?
解决方案
我认为问题在于您每次都在为您的 TOTP 生成一个新密钥。相反,您应该针对正在登录的用户保存密钥,以便始终针对相同的密钥进行验证。我假设您以某种方式(通过 QR 码?)向用户共享密钥,以便他们可以将其添加到身份验证器应用程序并生成令牌。
另一件事,我注意到您将令牌转换为整数。标记应该是字符串,因为它们可能包含前导零,您会因为转换为整数而丢失这些零。
推荐阅读
- typescript - 如何在打字稿中为所有私有方法和属性公开的类创建类型
- sql - 使用 SQL 查询标记错误的行
- android - ExoPlayer PlayerView 在设置“resizeMode”时会扩大宽度,而布局被限制为仅使用屏幕的 50%
- go - 本地包和目录结构
- sql - 读取 oracle 表中的 BLOB 列
- git - 将存储库添加为另一个存储库的分支及其所有历史记录
- maven - 获取 Maven 原型列表时出错
- css - 当宽度是容器的四分之一时,为什么 flex child 会跳到下一行?
- android - Xamarin.Plugin.FilePicker - content:/com.android.providers.downloads.documents 问题
- mysql - 在 Hibernate/JPA Generated UPDATE Query 的 Where 子句中包含附加列