auth

package
v0.0.1-beta.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: AGPL-3.0 Imports: 10 Imported by: 0

Documentation

Overview

Package auth 承载用户认证体系:bcrypt 密码哈希(与 sub2api 同参数)、 JWT 签发/验证(HS256,TTL 24h)与 RBAC 中间件(/user 组 RequireJWT + 快照用户状态校验;/admin = platform_admin JWT OR platform_admin 管理 key)。

Index

Constants

View Source
const DefaultTTL = 24 * time.Hour

评审定夺①:JWT 密钥 config 强制(C3API_JWT_SECRET),缺失启动失败—— 随机生成 = 重启全失效 + 多实例不一致。 评审定夺②:TTL 24h(用户决策 2026-08-11,原 15min 短时效导致日常使用频繁掉线)。 降权即时生效 = adminAuth 快照 role 覆盖 claims.Role(见 internal/server/ middleware.go adminAuth——快照刷新 ≤Reload 周期即生效);TTL 只约束 token 本身有效期,快照失效后长 TTL 仍作最终兜底。

Variables

View Source
var (
	ErrInvalidToken = errors.New("auth: invalid token")
	ErrTokenExpired = errors.New("auth: token expired")
)
View Source
var ErrPasswordTooLong = errors.New("auth: password exceeds 72 bytes (bcrypt limit)")

ErrPasswordTooLong bcrypt 截断限制(≤72 字节;注册/改密拒绝超长)。

Functions

func HashPassword

func HashPassword(plain string) (string, error)

HashPassword bcrypt DefaultCost(10),与 sub2api 完全一致——sub2api 迁移 存量 hash 直接可验证(同参数)。

func RequireIdentity

func RequireIdentity(iss *Issuer, p SnapshotProvider) func(http.Handler) http.Handler

RequireIdentity /user 组(含供应商面)统一身份鉴权中间件(spec 2026-10-09 §4.3): Bearer 凭证既可为 JWT(eyJ…)亦可为管理 key(mk-…),二者均以 owner/user 身份 放行。单一 SnapshotProvider(users + mgmt 合并)——同一 auth 只传一次。前缀先判:

  • mk- 开头 → 管理 key 快照查表(失败/禁用 → 401,**不回落 JWT**),owner 快照 缺失/非 active → 401(fail-closed);成功注入 Claims{UserID, Ver:sn.TokenVersion, Role:sn.Role} + FundsActor{UserID, TokenVersion:sn.TokenVersion}。
  • 非 mk- → 既有 JWT 校验(Verify + 快照 status/TokenVersion),同样注入 Claims + FundsActor。

两条分支都注入 ctxClaimsKey(下游 RequireRole / SupplierScopeInject / handler 读 auth.ClaimsFrom)与 FundsActor(资金命令 actor = owner,token_version = owner 快照 当前值——与 JWT 路径逐位一致,资金写事务复核通过)。不改动导出的 RequireJWT (他处/测试仍用)。

func RequireJWT

func RequireJWT(iss *Issuer, users UserStatusProvider) func(http.Handler) http.Handler

RequireJWT /user 组中间件:验证 Bearer JWT + 内存快照用户状态校验。 用户禁用 → 立即拒绝(快照刷新走 invalidate);JWT 24h 长时效仅作快照 失效后的最终兜底(评审定夺②,用户决策 2026-08-11)。

func RequireRole

func RequireRole(users UserStatusProvider, roles ...domain.Role) func(http.Handler) http.Handler

RequireRole 端点级 RBAC 声明:**快照 role ∈ 允许角色**(fail-closed—— 快照缺失即拒;与 RequireJWT/adminAuth 同源快照,降权在下一次成功 auth-sync 刷新后生效,§2.6)。就地改造为快照基(原读 claims.Role;RequireJWT 与 adminAuth 均读快照,本函数须一致,否则违反 fail-closed)。supplier 面用法: RequireJWT(users) → RequireRole(users, domain.SupplierSurfaceRoles()...)。

func ValidatePasswordLen

func ValidatePasswordLen(plain string) error

ValidatePasswordLen 密码 ≤72 字节校验(bcrypt 截断限制;超长拒绝而非 静默截断)。

func VerifyPassword

func VerifyPassword(hash, plain string) bool

VerifyPassword 校验明文与 bcrypt hash(sub2api 同参数 hash 直接可验证)。

Types

type Claims

type Claims struct {
	UserID int64  `json:"user_id"`
	Email  string `json:"email"`
	Role   string `json:"role"`
	Ver    int64  `json:"ver"`
	jwt.RegisteredClaims
}

Claims JWT 载荷:userID/email/role/ver/exp(HS256)。Ver = 签发时的 users.token_version 快照(spec 2026-08-25-jwt-password-revocation):改密/ 重置密码原子递增版本号,RequireJWT/adminAuth 与内存快照比对,不等 → 401 ——撤销该用户全部既有 JWT,无需 Redis denylist(版本语义"只认最新", 天然有界零额外读;存量票 ver 缺失解码 0 = DB 默认 0 ⇒ 升级平滑)。

func ClaimsFrom

func ClaimsFrom(ctx context.Context) (*Claims, bool)

ClaimsFrom 从请求 context 取已验证 claims(RequireJWT 之后可用)。

type Issuer

type Issuer struct {
	// contains filtered or unexported fields
}

Issuer JWT 签发/验证器(单实例;HS256)。

func NewIssuer

func NewIssuer(secret string) *Issuer

NewIssuer 构造签发器(TTL = DefaultTTL 24h)。

func (*Issuer) Issue

func (i *Issuer) Issue(userID int64, email, role string, ver int64) (string, error)

Issue 签发 HS256 JWT。ver = 用户当前 token_version(登录/注册时从 domain.User 透传;改密后旧版本号全部失效——撤销机制核心)。

func (*Issuer) Verify

func (i *Issuer) Verify(token string) (*Claims, error)

Verify 验证签名与过期,返回 claims。任何失败(签名错/篡改/过期/算法不符) 均返回错误(区分过期以便调用方选择文案)。

type ManagementKeyProvider

type ManagementKeyProvider interface {
	AuthenticateManagement(r *http.Request) (domain.ManagementKeyMeta, bool)
}

ManagementKeyProvider 管理 key 鉴权快照面(proxy.Auth 实现,spec 2026-10-09): 仅认 Authorization: Bearer mk-…;前缀先判、失败不回退 JWT(由调用方纪律保证)。

type SnapshotProvider

type SnapshotProvider interface {
	UserStatusProvider
	ManagementKeyProvider
}

SnapshotProvider 单一鉴权快照面(spec 2026-10-09 §4.3):合并用户状态与 管理 key 两个 provider——同一 auth 只传一次。proxy.Auth 同时实现两者。

type UserStatusProvider

type UserStatusProvider interface {
	UserSnapshot(userID int64) (domain.UserSnapshot, bool)
}

UserStatusProvider 用户快照(status+role 单次查找;proxy.Auth 实现;用户 变更走 invalidate → Auth.Reload 全量刷新,RequireJWT/adminAuth 不用 DB 直查——评审定夺②)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL