Flask登录流API服务器开发疑问:密码哈希存储与验证
登录API的密码存储与验证实现方案
结论:必须存储哈希后的密码
绝对不能在字典(或任何存储介质)里存明文密码——一旦数据泄露,用户的密码会直接暴露,风险极高。哈希算法是单向不可逆的,存储哈希值后,即使数据被窃取,也无法还原出原密码,能大幅提升系统安全性。
具体实现步骤(基于你的Flask代码)
我们可以用Flask依赖的werkzeug.security模块里的密码哈希工具,无需额外安装包,简单易用:
- 预先生成密码哈希值
先把USER_DICT里的明文密码替换成哈希后的字符串。可以先运行一段小代码生成哈希:
from werkzeug.security import generate_password_hash # 生成密码"12345"的哈希值 hashed_pwd = generate_password_hash("12345") print(hashed_pwd) # 输出类似:pbkdf2:sha256:260000$xxxxxx$xxxxxx...
然后把这个哈希值放到你的USER_DICT中:
USER_DICT = {"user": "ben", "password": "这里填上面生成的哈希字符串"}
- 修改登录接口的验证逻辑
登录时用check_password_hash方法,对比用户输入的明文密码和存储的哈希值,验证通过后再签发JWT:
完整修改后的代码:
from flask import Flask, request, jsonify, Response import jwt from werkzeug.security import check_password_hash app = Flask(__name__) # 替换成你生成的哈希密码 USER_DICT = {"user": "ben", "password": "pbkdf2:sha256:260000$abc123$d41d8cd98f00b204e9800998ecf8427e"} @app.route('/login', methods=['POST']) def login(): if "user" not in request.json or "password" not in request.json: return Response( "missing credentials", status=400, ) user_input = request.json["user"] pwd_input = request.json["password"] # 验证用户名是否存在 stored_user = USER_DICT.get("user") if stored_user != user_input: return Response("invalid credentials", status=401) # 验证密码哈希是否匹配 stored_pwd_hash = USER_DICT.get("password") if not check_password_hash(stored_pwd_hash, pwd_input): return Response("invalid credentials", status=401) # 验证通过,签发JWT encoded_jwt = jwt.encode({"sub": user_input}, "your-secret-key", algorithm="HS256") return jsonify({"token": encoded_jwt}) if __name__ == '__main__': app.run(debug=True)
额外注意事项
- 不要硬编码密钥:示例里的JWT密钥
"your-secret-key",生产环境要放到环境变量中,比如用os.getenv("JWT_SECRET_KEY")读取。 - 哈希算法选择:werkzeug默认使用的PBKDF2+SHA256是安全可靠的,无需自行寻找其他算法,避免踩坑。
- 错误提示统一:验证用户名或密码失败时,统一返回"invalid credentials",不要区分错误类型,防止攻击者枚举合法用户名。
内容的提问来源于stack exchange,提问作者Alo
相关产品推荐
相关产品推荐

