问题描述
使用 passlib
生成一次性密码(带有 N 个符号的短信密码)的最简单方法是什么?
我现在是如何创建它的:
from secrets import randbelow as secrets_randbelow
def create_secret_code() -> str: # Todo use OTP
secret_code = "".join([str(secrets_randbelow(exclusive_upper_bound=10)) for _ in range(config.SECRET_CODE_LEN)])
print_on_stage(secret_code=secret_code)
return secret_code
显然,它需要检查生成的代码已经不在使用中(例如 - 通过 Redis 制作)。
我的代码中也已经有一个 passlib
对象来散列和验证密码
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"],deprecated="auto")
我找到了 this 类,但不知道如何仅生成具有 N 个符号长度的 sms 密码
附言我添加了一个 fastapi
标签,因为我使用的是 fastapi
并且 passlib
用作它的标准加密工具,docs
解决方法
您可以使用令牌所需的位数初始化 TOTP 类,如下所示:
TOTP(digits=10)
这是一个完整的示例,使用您的 config.SECRET_CODE_LEN
:
from passlib.totp import TOTP
otp = TOTP('s3jdvb7qd2r7jpxx',digits=config.SECRET_CODE_LEN)
token = otp.generate()
print(token.token)