session_token.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. package auth
  2. // 会话的「是否通过过 TOTP」标记。
  3. //
  4. // docs/backend/auth.md 6.2 要求 totp_verified 表示「会话创建时通过过 TOTP」,
  5. // 但 sessions 表(auth.md 第三节)没有该字段。为此在会话记录里串上标记:
  6. //
  7. // <会话随机串> → 未通过 TOTP 创建
  8. // <会话随机串>:totp → 通过 TOTP 创建
  9. //
  10. // cookie 里下发明文,数据库存剥离后缀后的 SHA-256。与 pending_logins 的
  11. // trust_device 标记(auth.md 3.1 规则 1)是同一手法:不新增列、明文不落库。
  12. const sessionTotpSuffix = ":totp"
  13. // newSessionTokenFor 生成会话 token,并按需带 TOTP 标记。
  14. func newSessionTokenFor(totpVerified bool) (string, error) {
  15. tok, err := newSessionToken()
  16. if err != nil {
  17. return "", err
  18. }
  19. if totpVerified {
  20. return tok + sessionTotpSuffix, nil
  21. }
  22. return tok, nil
  23. }
  24. // splitSessionToken 剥离会话 token 末尾的 TOTP 标记。
  25. // 返回「用于哈希的原始值」与「是否通过过 TOTP」。
  26. func splitSessionToken(plain string) (token string, totpVerified bool) {
  27. if len(plain) > len(sessionTotpSuffix) && plain[len(plain)-len(sessionTotpSuffix):] == sessionTotpSuffix {
  28. return plain[:len(plain)-len(sessionTotpSuffix)], true
  29. }
  30. return plain, false
  31. }
  32. // sessionLookupHash 计算会话查库用的哈希:先剥离标记,再哈希。
  33. func sessionLookupHash(plain string) string {
  34. base, _ := splitSessionToken(plain)
  35. return HashToken(base)
  36. }
苏ICP备2026082406号
苏公网安备 待审核