调用原因(起因)

为了给一个Python程序加一个双因素认证功能,提高安全性,后来我就想如何在不使用短信(没钱)和邮件发送(容易进垃圾邮件)的情况下去生成验证码,后面想想Google Authenticator不就符合我的要求吗?后面去Google一下,原来用的是TOTP标准。

Example Code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import sys, pyotp, datetime
if sys.argv.count == 2 :
    OTPSecret = sys.argv[1]
    ShowSecret = 0
else:
    OTPSecret = pyotp.random_base32()
    ShowSecret = 1

TOTPObject = pyotp.TOTP(OTPSecret)

if ShowSecret == 1 :
    print("You are in test mode.")
    print("The Test Secret is " + OTPSecret)
    print("Test Add Url: " + pyotp.totp.TOTP(OTPSecret).provisioning_uri(issuer_name='Test App', name='test@example.com'))

PassStatus = False

while PassStatus == False:
    print("Now is " + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    UserInput = input("Give me a code. It's 6 digitals.")
    PassStatus = TOTPObject.verify(UserInput)
    if PassStatus == False:
        print("It's wrong. Please try it again.")

print("Passed.")

目前bug

输入超过6位的话,程序会蹦,记得加位数验证。

执行结果

1
2
3
4
5
6
7
8
9
You are in test mode.
The Test Secret is 5ADHPNSTNDFWMMYR
Test Add Url: otpauth://totp/Test%20App:test%40example.com?secret=5ADHPNSTNDFWMMYR&issuer=Test%20App
Now is 2020-06-06 18:30:17
Give me a code. It's 6 digitals.123456
It's wrong. Please try it again.
Now is 2020-06-06 18:30:21
Give me a code. It's 6 digitals.535186
Passed.

注意事项

TOTP是每30秒更新一次的,要保证服务器时间与用户时间相差不能太大。