认证与权限(Auth 服务)
认证已从 api 中拆出为独立的 Auth 服务(internal/auth),承担注册/登录/资料/JWKS 与用户查询,实现密钥隔离:api 不持私钥,仅通过 JWKS 本地无状态验签。
为什么拆分 Auth?
| 收益 | 说明 |
|---|---|
| 安全隔离 | RSA 私钥只存在于 auth 服务,api/worker/transcoder 均不持有,泄露面最小化 |
| 密钥轮换 | 更换私钥只需重启 auth + JWKS 缓存刷新,不影响业务服务 |
| 无状态验签 | api 通过 JWKS 缓存公钥本地验签,不回调 auth、不引入额外 RTT |
| 独立扩容 | 认证流量与业务流量互不挤占 |
| 未来演进 | 令牌撤销、SSO、多租户等能力可独立演进 |
整体架构
text
┌────────── 客户端 ──────────┐
│ 注册 / 登录 / 资料 │
└─────────────┬──────────────┘
│ HTTP(Traefik 分流 /api/v1/auth|user → auth:8081)
▼
┌───────────────────────────────┐
│ Auth 服务(持有 RSA 私钥) │
│ ├─ HTTP :8081 │
│ │ ├─ POST /api/v1/auth/register │
│ │ ├─ POST /api/v1/auth/login │
│ │ ├─ GET/PUT /api/v1/user/* │
│ │ └─ GET /.well-known/jwks.json │
│ ├─ gRPC :50052(用户查询,etcd 注册)│
│ └─ 签发 RS256 JWT │
└─────────────┬────────────────┘
│ JWKS 公钥(HTTP 拉取 + 每小时刷新)
▼
┌───────────────────────────────┐
│ api 服务(不持私钥) │
│ ├─ TokenVerifier:JWKS 本地验签 │
│ └─ authclient:gRPC 用户查询 │
└───────────────────────────────┘密钥管理
go
// internal/role/auth.go:loadOrGeneratePrivateKey 三级来源
1. VISTACK_AUTH_RSA_PRIVATE_KEY // 环境变量 PEM 字符串(生产推荐)
2. VISTACK_AUTH_RSA_PRIVATE_KEY_FILE // PEM 文件路径(Docker Secret / K8s Secret 挂载)
3. 运行时生成临时密钥 // 仅开发:进程内有效,重启即失效(日志告警)bash
# 生成 RSA 私钥(一次性)
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
# 注入(容器示例)
VISTACK_AUTH_RSA_PRIVATE_KEY_FILE=/run/secrets/private.pem docker compose up -d authToken 设计(RS256 + JWKS)
- 算法:RS256(非对称),私钥签发(auth)、公钥验签(api);
- Claim:
kid(key id)、iss(issuer,默认vistack)、exp(过期,默认 3600s)、用户 ID / 角色等; - JWKS 端点:
GET /.well-known/jwks.json发布公钥; - api 验签:
authpkg.NewTokenVerifier(jwksURL)首次拉取 JWKS 后缓存,每 1 小时自动刷新;验证失败才重新拉取(容错)。
go
// internal/role/api.go
verifier := authpkg.NewTokenVerifier(jwksURL)
verifier.StartAutoRefresh(ctx, time.Hour)RBAC 权限模型
RBAC 采用「authorities(权限) + 角色/用户两级授权」:
| 表 | 说明 |
|---|---|
authorities | 权限点(资源方法 + URI),如 video:create、video:delete |
roles | 角色(如 admin / user) |
role_authority | 角色-权限关联 |
user_authority | 用户-权限直接关联(绕过角色的直接授权) |
users.role | 用户主角色 |
权限判定链:用户直接权限(user_authority) ⊃ 角色权限(role_authority),中间件校验 JWT 中的身份后按资源方法 + URI 匹配。
接口清单
| 方法 | 路径 | 说明 | 鉴权 |
|---|---|---|---|
| POST | /api/v1/auth/register | 注册(密码 bcrypt 哈希) | 公开 |
| POST | /api/v1/auth/login | 登录(返回 JWT + 用户信息) | 公开 |
| GET | /api/v1/user/info | 当前用户信息 | Bearer Token |
| PUT | /api/v1/user/profile | 更新资料 | Bearer Token |
| PUT | /api/v1/user/password | 修改密码 | Bearer Token |
| GET | /.well-known/jwks.json | JWKS 公钥 | 公开 |
| gRPC | UserService.GetUser | 用户批量查询(api 展示作者信息) | 内网 |
登录后限流
Auth 接口同样接入 分布式限流,登录接口按用户 ID 限流,防暴力破解。
演进方向(roadmap)
- gRPC mTLS 鉴权(transcoder / auth 间加密);
- 令牌撤销与刷新令牌(Refresh Token);
- SSO / OAuth2 集成。
