How to get OTP token for an existing user in django using django-two-factor-auth

0

I am writing selenium tests for django. I want to login a user with OTP through UI using selenium. After login , I get the setup page where I am supposed to enter a 6 digit token generated by google authenticator. django-two-factor-auth stores a secret key per user in table otp_totp_totpdevice . I assume google authenticator is supposed to use this key to generate the token.

Following is what I have tried so far: it generates a wrong token.

import hmac, base64, struct, hashlib, time


def get_hotp_token(secret, intervals_no):
    key=base64.b64decode(secret,validate=True)
    msg = struct.pack(">Q", intervals_no)
    h = hmac.new(key, msg, hashlib.sha1).digest()
    o = h[19] & 15
    h = (struct.unpack(">I", h[o:o + 4])[0] & 0x7fffffff) % 1000000
    return h


def get_totp_token(secret):
    return get_hotp_token(secret, intervals_no=int(time.time()) // 30)
python
django
google-authenticator
django-two-factor-auth
asked on Stack Overflow Sep 15, 2020 by Aseem

2 Answers

0

If we have a user who doesnt have OTP created yet, lets create one:

device = user.totpdevice_set.create(name='default')

If our user already has OTP created, then ignore above step. To get token do following:

from django_otp.oath import totp

device = user.totpdevice_set.get()
token = totp(device.bin_key)
print(token)
answered on Stack Overflow Sep 15, 2020 by Aseem
0

Solved this problem with PyOTP library

once you have the device...

import pyotp


uri = device.config_url
parsed_uri = pyotp.parse_uri(uri)
secret = parsed_uri.secret
otp_token = pyotp.TOTP(secret).now()
answered on Stack Overflow Jan 29, 2021 by Medanko

User contributions licensed under CC BY-SA 3.0