地址:https://github.com/pyauth/pyotp
Python One-Time Password Library
安装依赖
pip install pyotp qrcode[pil]
生成二维码
import pyotp
import qrcode
from PIL import Image
def generate_2fa_qrcode(username, issuer_name, secret_key=None, save_path=None):
"""
生成两步验证的二维码图片
参数:
username (str): 用户名,将显示在认证APP中
issuer_name (str): 发行者名称,将显示在认证APP中
secret_key (str, optional): 如果提供则使用指定的密钥,否则生成随机密钥。默认None
save_path (str, optional): 二维码图片保存路径。默认None(不保存)
返回:
tuple: (secret_key, qr_image_object)
"""
# 生成或使用提供的密钥
secret_key = secret_key or pyotp.random_base32()
# 创建TOTP对象
totp = pyotp.TOTP(secret_key)
# 生成用于认证APP的URI
provisioning_uri = totp.provisioning_uri(name=username, issuer_name=issuer_name)
# 创建二维码
qr = qrcode.QRCode(
version=1,
error_correction=qrcode.constants.ERROR_CORRECT_L,
box_size=10,
border=4,
)
qr.add_data(provisioning_uri)
qr.make(fit=True)
# 生成二维码图片
img = qr.make_image(fill_color="black", back_color="white")
# 保存二维码(如果指定了路径)
if save_path:
img.save(save_path)
return secret_key, img
验证
def verify_2fa_code(secret_key, user_code, valid_window=1):
"""
验证用户输入的验证码是否正确
参数:
secret_key (str): 用于验证的密钥(必须与生成二维码时使用的相同)
user_code (str): 用户从认证APP输入的验证码
valid_window (int, optional): 允许的时间窗口偏移量(每个窗口30秒)。默认1
返回:
bool: 验证是否通过
"""
# 创建TOTP对象
totp = pyotp.TOTP(secret_key)
# 验证用户输入的验证码
# 考虑到时间同步问题,valid_window允许验证前后窗口的验证码
return totp.verify(user_code, valid_window=valid_window)