bcrypt.generatefrompassword调用失败需先校验密码非空且长度≤72字节,使用bcrypt.defaultcost(推荐12),哈希后转string存入varchar(255)字段,避免截断或空值导致登录比对失败。

用户注册时密码没加密,bcrypt.GenerateFromPassword 调用失败怎么办
Go Fiber 本身不处理密码哈希,得自己集成 golang.org/x/crypto/bcrypt。常见错误是传入空密码、长度超限(bcrypt 最多支持 72 字节)或忘记处理错误返回。
- 先校验
password非空且长度 ≤ 72,否则bcrypt.GenerateFromPassword会 panic 或静默失败 - 用
bcrypt.DefaultCost(通常为 12)足够,别盲目调高——CPU 开销指数级增长,登录验证也会变慢 - 别把原始密码存进数据库;加密后只存
hash字符串(通常是 60 字符,以$2a$或$2b$开头)
示例片段:
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
c.Status(fiber.StatusBadRequest).JSON(fiber.Map{"error": "密码加密失败"})
return
}
登录接口里 bcrypt.CompareHashAndPassword 总返回 crypto/bcrypt: hashedPassword is not the hash of the given password
这个错误几乎都因为数据库里存的不是完整哈希字符串,或者读取时被截断、trim 过、加了额外空格。
- 查数据库确认字段类型是
VARCHAR(255)(别用CHAR(60),不同 bcrypt 版本哈希长度可能略有差异) - 用
fmt.Printf("len: %d, val: '%s'\n", len(storedHash), storedHash)打印实际值,看有没有隐藏字符或长度异常 - 确保查询 SQL 没用
TRIM()或UPPER()类函数处理哈希字段 - 对比时传入的是
[]byte(storedHash)和[]byte(inputPassword),别反了顺序
用 fiber.JWT 做鉴权,但刷新 token 时 c.Locals("user") 拿不到用户信息
JWT 中间件默认只解析 token 并挂载到 c.Locals,但不会自动查库补全用户数据。刷新逻辑必须自己实现,不能依赖中间件“自动续命”。
- 刷新接口需先校验旧 token 有效性(用
jwt.New+Parse),再从 payload 提取user_id(别信前端传的) - 查库确认该用户仍有效(比如没被禁用)、token 没在黑名单(如有维护
blacklist表) - 生成新 token 时,payload 里只放必要字段(如
id,exp),别塞完整用户对象——体积大、泄露风险高 - 别把 refresh token 存 cookie 且设
HttpOnly=false,容易被 XSS 窃取
用户列表接口加分页,db.Offset().Limit() 在 MySQL 和 PostgreSQL 行为不一致
Fiber 不管 ORM,你用 gorm 或 sqlx 时,分页参数传递方式和 SQL 渲染逻辑由底层驱动决定,不是框架问题。
-
Offset(n).Limit(m)在 GORM 中对 MySQL 和 PG 都可用,但注意:MySQL 的LIMIT m OFFSET n和 PG 的LIMIT m OFFSET n语义一致,可放心用 - 真正坑的是“跳过前 N 条”的性能——当
n很大(比如第 10000 页),数据库要扫描前 N+M 行。线上环境务必加created_at或id游标分页替代 - 别信任前端传的
page和limit,做范围校验:limit限制在 10–100,page不能负数
游标分页更稳,比如 WHERE id > ? ORDER BY id LIMIT ?,但需要前端传上次响应的末尾 id。











