全栈课的底线不是功能跑通,是别把用户数据送出去。这一页对应课程标准明确的素质目标—— 「具备安全编码意识(SQL 注入、密码加密、接口鉴权)」。每个要点都用「错误写法 → 正确写法」对照讲, 配合「古典文学网」后端 hiflask 的真实代码位置,学完能直接回项目里自查。
' OR '1'='1 就能绕过条件、甚至删库。# 用 f-string 拼接用户输入 —— 千万别这么写
sql = f"SELECT * FROM users WHERE name = '{username}'"
db.execute(sql) # username="' OR '1'='1" 时条件永远为真
# 占位符,参数与 SQL 分离,注入无处下手
sql = "SELECT * FROM users WHERE name = %s"
db.execute(sql, (username,))
# 或直接用 SQLAlchemy ORM(本项目 hiflask 的做法)
User.query.filter_by(name=username).first()
hiflask 全程用 SQLAlchemy,天然规避拼接注入。from werkzeug.security import generate_password_hash, check_password_hash
# 注册:存哈希,不存明文
pwd_hash = generate_password_hash(raw_password) # 自带盐值 + pbkdf2/sha256
# 登录:比对哈希,不是比对明文
if check_password_hash(user.password, raw_password):
... # ✅ 密码正确
sql/hiwen.sql 的种子账号密码为 PUT_HASH_HERE 占位,上线前须替换为真实 generate_password_hash 结果。# 登录成功签发 token
token = jwt.encode({"uid": user.id, "exp": now+3600}, SECRET, algorithm="HS256")
# 受保护接口校验 token,取不到 / 过期都拒绝
payload = jwt.decode(token, SECRET, algorithms=["HS256"]) # 抛异常即 401
uid = payload["uid"]
beforeEach 里检查是否有合法 token,无则跳登录页(本项目 hivue 已封装)。.env,别硬编码进仓库。后端跨域别图省事写 allow_origins=["*"]。开发期放开,生产期只列前端域名白名单,避免任意站点调你的接口。
头像上传要校验类型、限制大小、用 uuid4 随机文件名(本项目已做)。绝不一上来就 save(request.file) 用原文件名。
数据库密码、JWT 密钥、云存储 key 一律进 .env 并加入 .gitignore,代码里只读环境变量。
check_password_hash。做完点「检查本节」看解析与得分;做错可重做。