1

I am using two-factor authentication for a Django project. It is working fine but I want to implement few more features in my code. But I am unable to implement

Expected Behavior:

I want that a user has to face a 2F authentication prompt whenever the user logins from a new device. Also, I want to increase code validation time.

Current Behavior:
Currently, if a user logins for the first time, the user is shown an authentication prompt. But when the user logins from a new device, the user is not shown an authentication and easily logs in. But I want that the user has to face 2F from every new device. Also Whenever I change a step the validate code does not valid. For example, if I give step=60, then the validation code gets invalid. I am unable to increase the time for code validation.

I checked the TOTPDevice model in the database. It shows that now a new key is not generating for the new device.

I am using the below codes.

def get_user_totp_device(self, user, confirmed=None):
    """
    Gets user's time based one-time password devices
    """
    devices = devices_for_user(user, confirmed=confirmed)
    for device in devices:
        if isinstance(device, TOTPDevice):
            return device

class TOTPCreateView(APIView):
permission_classes = []

def post(self, request):
    username = request.data['username']
    user = User.objects.get(username=username)
    user_email = user.email
    user_device = request.META.get('HTTP_USER_AGENT', '')
    time = datetime.now().strftime("%H:%M:%S")
    if not user.is_anonymous:
        device = get_user_totp_device(self, user)
        if not device:
            device = user.totpdevice_set.create(confirmed=False)
            secret_key = device.bin_key
            totp = pyotp.TOTP(base64.b32encode(secret_key))
            one_time_password = totp.now()
        url = device.config_url

        response_status = status.HTTP_201_CREATED
    else:
        url = {}
        response_status = status.HTTP_401_UNAUTHORIZED

    return Response(url, status=response_status)

class TOTPVerifyView(APIView):
permission_classes = []

def post(self, request, token, format=None):
    username = request.data['username']
    user = User.objects.get(username=username)
    device = get_user_totp_device(self, user)

    if not user.is_anonymous:
        device_registered = device.verify_token(token)
        if device_registered:
            if not device.confirmed:
                device.confirmed = True
                device.save()
            data = True
            response_status = status.HTTP_200_OK
        else:
            data = {'error': 'Verification code is not valid'}
            response_status = status.HTTP_400_BAD_REQUEST
    else:
        data = False
        response_status = status.HTTP_401_UNAUTHORIZED

    return Response(data, status=response_status)