You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask集成pytotp实现OTP校验时验证不通过问题求助

问题根因
  • 核心错误为TOTP时间窗口参数不匹配:你在生成OTP时创建TOTP实例指定了interval=60(60秒有效期),但校验时创建的TOTP实例没有加该参数,使用pytotp默认的30秒间隔,两边时间窗口完全不一致,导致校验必然失败。
  • 潜在问题:未做参数归一化处理,若客户端传参携带空格、或otp为数字类型,也可能导致校验失败;若服务端与客户端时间存在轻微偏差,无容错配置也会触发校验失败。
修正后的完整实现代码
import pyotp
from flask import Flask, request, jsonify, make_response

app = Flask(__name__)

@app.route('/get-otp-secret', methods=['POST'])
def get_otp_secret():
    return make_response(jsonify(generate_otp_secret()), 201)

@app.route('/verify-otp', methods=['POST'])
def verify_otp():
    otp = request.form.get('otp')
    secret = request.form.get('secret')
    return jsonify(verify_otp_value(otp, secret))

def generate_otp_secret():
    secret = pyotp.random_base32()
    # 生成时的interval参数要和校验时完全一致
    totp = pyotp.TOTP(secret, interval=60)
    current_otp = totp.now()
    return {
        'secret': secret,
        'otp': current_otp
    }

def verify_otp_value(otp, secret):
    # 先做参数归一化处理,去除空格、统一为字符串类型
    otp = str(otp).strip()
    secret = str(secret).strip()
    # 校验时使用和生成时完全相同的interval配置
    totp = pyotp.TOTP(secret, interval=60)
    # 增加valid_window参数,允许前后1个时间窗口的误差,解决轻微时间不同步问题
    return totp.verify(otp, valid_window=1)
额外排查建议
  • 先做服务端本地自测:调用generate_otp_secret拿到密钥和OTP后,直接调用校验函数测试,确认本地校验正常后再排查客户端传参问题
  • 打印校验时的对比值:在校验函数中打印当前服务端生成的OTP值、客户端传入的OTP值,确认参数传输过程中没有被转义或修改
  • 确认Android端Retrofit传参配置:不要对OTP、secret参数做额外的URL编码或Base64转义,保证传参和服务端返回的原始值完全一致

内容的提问来源于stack exchange,提问作者Shivank Anchal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 14:45:00