首页 > 解决方案 > 使用 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。我在这里做错了吗?

标签: pythondjangorestdjango-rest-frameworktwo-factor-authentication

解决方案


我认为问题在于您每次都在为您的 TOTP 生成一个新密钥。相反,您应该针对正在登录的用户保存密钥,以便始终针对相同的密钥进行验证。我假设您以某种方式(通过 QR 码?)向用户共享密钥,以便他们可以将其添加到身份验证器应用程序并生成令牌。

另一件事,我注意到您将令牌转换为整数。标记应该是字符串,因为它们可能包含前导零,您会因为转换为整数而丢失这些零。


推荐阅读