关于 auth-ops
auth-ops 是面向开发者的身份验证与授权参考技能,涵盖多种语言和框架。内容按决策树、速查表、安全检查清单及专题文件组织。
主要功能
- 01身份验证策略决策树
- 02JWT 与 OAuth2 指南
- 03授权模型参考
- 04会话与 Cookie 安全
- 05密码和 MFA 检查清单
- 06身份代理安全指南
适用场景
- 01为应用选择身份验证流程
- 02检查 JWT 声明与令牌处理
- 03规划角色、权限或策略模型
- 04核对会话、密码和 MFA 做法
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ 0xdarkmatter/ claude-mods --skill auth-ops安装后在 Claude Code 中输入/auth-ops确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/.gitkeepreferences/authorization.mdbetter-auth.mdcloudflare-access.mdimplementation.mdjwt-sessions.mdoauth2-oidc.mdscripts/.gitkeep详细介绍
认证操作
适用于多种语言和框架的全面身份验证与授权模式,助力安全应用开发。
身份验证方法决策树
使用此决策树为你的用例选择合适的身份验证策略。
What are you building?
│
├─ Traditional web application (server-rendered)?
│ └─ Session-based authentication
│ ├─ Server stores session data (Redis/DB)
│ ├─ Session ID in httpOnly cookie
│ └─ Best for: monoliths, SSR apps, admin panels
│
├─ API consumed by multiple clients?
│ └─ JWT (JSON Web Tokens)
│ ├─ Stateless, self-contained tokens
│ ├─ Access token (short-lived) + refresh token (long-lived)
│ └─ Best for: microservices, mobile apps, SPAs via BFF
│
├─ Service-to-service communication?
│ └─ API keys or Client Credentials (OAuth2)
│ ├─ API keys: simple, scoped, rotatable
│ ├─ Client Credentials: OAuth2 standard, token-based
│ └─ Best for: internal services, third-party integrations
│
├─ Third-party login (Google, GitHub, etc.)?
│ └─ OAuth2 / OpenID Connect
│ ├─ Authorization Code + PKCE for web/mobile
│ ├─ Delegate identity to trusted providers
│ └─ Best for: consumer apps, social login
│
├─ Passwordless authentication?
│ └─ Passkeys (WebAuthn) or Magic Links
│ ├─ Passkeys: phishing-resistant, biometric/hardware
│ ├─ Magic links: email-based, time-limited
│ └─ Best for: high-security, modern UX
│
└─ Internal tool / staff app with an existing IdP?
└─ Identity-aware proxy (Cloudflare Access)
├─ Authn enforced at the edge, before your origin
├─ Origin verifies the proxy's signed JWT (never a bare header)
└─ Best for: admin panels, partner portals, not consumer signup
JWT 快速参考
结构
Header.Payload.Signature
Header: { "alg": "RS256", "typ": "JWT" }
Payload: { "iss": "auth.example.com", "sub": "user_123", ... }
Signature: RSASHA256(base64(header) + "." + base64(payload), privateKey)
常见声明
| 声明 | 名称 | 用途 | 示例 |
|---|---|---|---|
iss | 签发者 | 谁签发了令牌 | "auth.example.com" |
sub | 主体 | 令牌代表谁 | "user_123" |
exp | 过期时间 | 令牌何时过期 | 1700000000(Unix 时间戳) |
iat | 签发时间 | 令牌何时创建 | 1699999100 |
aud | 受众 | 预期接收方 | "api.example.com" |
jti | JWT ID | 唯一令牌标识符 | "a1b2c3d4"(用于撤销) |
nbf | 生效时间 | 令牌在此时间前无效 | 1699999100 |
签名算法
| 算法 | 类型 | 密钥 | 适用场景 |
|---|---|---|---|
| RS256 | 非对称(RSA) | 公钥/私钥对 | 分布式系统、多个验证方 |
| ES256 | 非对称(ECDSA) | 公钥/私钥对 | 与 RS256 相同,但密钥/签名更小 |
| HS256 | 对称(HMAC) | 共享密钥 | 单一服务、简单配置 |
经验法则: 当令牌签发方和验证方是不同的服务时,使用非对称算法(RS256/ES256)。仅当同一服务同时创建和验证令牌时,才使用 HS256。
访问令牌 + 刷新令牌模式
┌──────────┐ ┌──────────┐
│ Client │─── login ────────>│ Auth │
│ │<── access (15m) ──│ Server │
│ │<── refresh (7d) ──│ │
│ │ └──────────┘
│ │─── API call ─────>┌──────────┐
│ │ (access token) │ Resource │
│ │<── response ──────│ Server │
│ │ └──────────┘
│ │─── access expired │ │
│ │─── refresh ──────>│ Auth │
│ │<── new access ────│ Server │
│ │<── new refresh ───│ (rotate)│
└──────────┘ └──────────┘
- 访问令牌: 有效期较短(5-15 分钟),用于 API 调用
- 刷新令牌: 有效期较长(7-30 天),用于获取新的访问令牌
- 轮换: 每次使用时签发新的刷新令牌,并使旧令牌失效
- 家族检测: 跟踪刷新令牌的继承关系;如果已撤销的令牌被重复使用,则使整个家族失效
OAuth2 流程决策树
What type of client?
│
├─ Web app with backend (Next.js, Rails, Django)?
│ └─ Authorization Code + PKCE
│ ├─ Redirect user to authorization server
│ ├─ Receive code at callback URL
│ ├─ Exchange code for tokens server-side
│ └─ PKCE prevents code interception attacks
│
├─ SPA (React, Vue) without backend?
│ └─ Authorization Code + PKCE (via BFF)
│ ├─ Use a Backend-for-Frontend to handle tokens
│ ├─ Never store tokens in browser-accessible storage
│ └─ BFF proxies API calls with token attached
│
├─ Mobile app (iOS, Android)?
│ └─ Authorization Code + PKCE
│ ├─ Use custom URI scheme or universal links for redirect
│ ├─ PKCE is mandatory (public client)
│ └─ Store tokens in secure enclave/keystore
│
├─ Server-to-server (no user)?
│ └─ Client Credentials
│ ├─ Authenticate with client_id + client_secret
│ ├─ No user context, service-level access
│ └─ Token cached until expiry
│
├─ CLI tool or smart TV?
│ └─ Device Code
│ ├─ Display code and URL to user
│ ├─ User authenticates on another device
│ ├─ CLI/TV polls for completion
│ └─ Good UX for input-constrained devices
│
└─ Microservice acting on behalf of a user?
└─ Token Exchange (RFC 8693)
├─ Exchange user's token for a scoped downstream token
├─ Maintains user context across services
└─ Use `act` claim for delegation chain
授权模型决策树
How complex are your access control needs?
│
├─ Simple: just "can user X do action Y"?
│ └─ Permission-based (direct)
│ ├─ user_permissions table
│ ├─ Simple to implement, hard to scale
│ └─ Good for: small apps, prototypes
│
├─ Users grouped into roles with fixed permissions?
│ └─ RBAC (Role-Based Access Control)
│ ├─ Roles: admin, editor, viewer
│ ├─ Each role has a set of permissions
│ ├─ Users assigned one or more roles
│ └─ Good for: most apps, admin panels, team tools
│
├─ Decisions depend on attributes (time, location, resource owner)?
│ └─ ABAC (Attribute-Based Access Control)
│ ├─ Policies evaluate subject + resource + environment attributes
│ ├─ "Allow if user.department == resource.department AND time < 17:00"
│ ├─ Flexible but complex
│ └─ Good for: enterprise, compliance-heavy, context-dependent access
│
└─ Access based on relationships (owner, parent, shared with)?
└─ ReBAC (Relationship-Based Access Control)
├─ Google Zanzibar model
├─ Tuples: user:alice#viewer@document:report
├─ Supports inheritance: folder viewer → document viewer
├─ Tools: OpenFGA, SpiceDB, Ory Keto
└─ Good for: file sharing, nested resources, social features
会话管理快速参考
Cookie 安全设置
| 设置 | 值 | 用途 |
|---|---|---|
SameSite | Strict | 仅在同站请求中发送 Cookie(最佳 CSRF 防护) |
SameSite | Lax | 在顶层导航时发送 Cookie(良好的默认设置) |
SameSite | None | 在跨站请求中发送 Cookie(需要 Secure) |
Secure | true | 仅通过 HTTPS 发送 Cookie |
HttpOnly | true | JavaScript 无法访问 Cookie(防止 XSS 窃取) |
__Host- 前缀 | 不适用 | 必须设置 Secure,不得设置 Domain,且 Path=/(最严格) |
__Secure- 前缀 | 不适用 | 必须设置 Secure 标志 |
Max-Age | 秒 | Cookie 有效期(优先于 Expires) |
Path | / | 将 Cookie 限定在指定路径范围内(通常为 /) |
推荐的 Cookie 配置
Set-Cookie: __Host-session=abc123;
Secure;
HttpOnly;
SameSite=Lax;
Max-Age=86400;
Path=/
会话过期策略
| 策略 | 典型值 | 说明 |
|---|---|---|
| 空闲超时 | 15-30 分钟 | 每次请求时重置 |
| 绝对超时 | 8-24 小时 | 强制重新进行身份验证 |
| 滑动窗口 | 空闲 30 分钟,最长 8 小时 | 最佳平衡 |
| 记住我 | 30 天 | 延长会话,降低权限 |
密码处理快速参考
哈希算法
| 算法 | 评价 | 说明 |
|---|---|---|
| argon2id | 最佳 | 内存困难型,可抵御 GPU 攻击,OWASP 推荐 |
| bcrypt | 良好 | 经受过实战检验,成本因子为 12+,输入上限为 72 字节 |
| scrypt | 良好 | 内存困难型,但库支持较少 |
| PBKDF2 | 可接受 | 符合 FIPS 标准,使用 SHA-256 时迭代次数应为 60 万次以上 |
| SHA-256/512 | 不佳 | 速度太快,未内置盐值,容易遭到暴力破解 |
| MD5 | 切勿使用 | 已被破解,彩虹表广泛可用 |
密码规则(NIST 800-63B)
| 规则 | 指引 |
|---|---|
| 最小长度 | 8 个字符(建议 12 个或更多) |
| 最大长度 | 至少 64 个字符 |
| 复杂度规则 | 不要要求使用特殊字符/大写字母/数字 |
| 泄露密码检查 | 检查密码是否出现在已知泄露密码中(HaveIBeenPwned API) |
| 密码提示 | 不允许 |
| 强制轮换 | 不要强制定期更改(仅在发生泄露时更改) |
| 粘贴到密码字段 | 允许(支持密码管理器) |
登录尝试频率限制
| 尝试次数 | 响应 |
|---|---|
| 1-5 | 正常登录 |
| 6-10 | 要求完成 CAPTCHA |
| 11-20 | 逐步延长等待时间(2 秒、4 秒、8 秒……) |
| 20+ | 临时锁定账户(15-30 分钟) |
重要: 对成功和失败的请求使用一致的响应时间,以防止通过计时差异枚举用户名。
MFA 快速参考
安全性排序
| 方法 | 安全性 | 用户体验 | 备注 |
|---|---|---|---|
| WebAuthn/Passkeys | 最高 | 良好 | 可抵御网络钓鱼,由硬件保护 |
| TOTP(身份验证器) | 高 | 中等 | 基于应用(Google/Microsoft Authenticator) |
| 推送通知 | 高 | 良好 | 需要移动应用 |
| 电子邮件 OTP | 中等 | 中等 | 取决于电子邮件安全性 |
| 短信 OTP | 低 | 简单 | 易受 SIM 卡交换攻击,仅用作备用方式 |
TOTP 实施清单
- 生成 160 位密钥(以 base32 编码)
- 构建包含签发方和账户信息的 otpauth:// URI
- 显示 QR 码,供身份验证器扫描
- 启用前要求验证首个验证码
- 接受当前时间窗口前后各 1 个间隔(每步 30 秒)
- 生成 8-10 个一次性备用码
- 存储前对备用码进行哈希处理
- 允许通过已验证的身份进行恢复
Passkey/WebAuthn 清单
- 在服务端生成加密质询
- 设置信赖方 ID(你的域名)
- 存储凭证公钥和 ID
- 在身份验证时验证签名
- 支持每个用户拥有多个凭证
- 处理平台验证器和跨平台验证器
- 提供备用身份验证方式
身份感知代理快速参考
当身份验证委托给代理边缘(Cloudflare Access、Google IAP、oauth2-proxy)时,以下两项不变条件构成了整个模型:
- 验证断言。 代理的身份标头是经过签名的 JWT——每次请求都要根据代理的 JWKS 验证签名、签发方和每个应用的受众。绝不要信任纯文本的便捷邮箱标头。
- 封闭绕过代理的所有路径。 只有当代理是访问源站的唯一途径时,标头才有意义(
workers_dev = false、为源站配置防火墙,或使用隧道)。源站开放会导致任何标头都可伪造。
Proxy edge (authn) ──JWT header──> Origin verifies JWT ──> app user lookup ──> role/scope binding
│ │ 403 on any failure │ 403 if no row (server-side)
└ IdP / OTP login, sessions └ cached JWKS, └ proxy admits ≠ app authorizes
rate limits, bot defense refetch on unknown kid
机器路由(webhooks、ingest)应在边缘使用 Service-Auth/Bypass,并在源站使用 bearer 密钥,挂载在面向人类用户的身份验证中间件之外。完整说明见:references/cloudflare-access.md。
常见陷阱
| 陷阱 | 危险原因 | 修复方法 |
|---|---|---|
| 将 JWT 存储在 localStorage 中 | XSS 可窃取令牌,浏览器不会强制令牌过期 | 使用 httpOnly Cookie 或 BFF 模式 |
| OAuth2 中缺少 PKCE | 可能遭受授权码拦截攻击 | 始终使用 PKCE,即使是机密客户端也不例外 |
| RBAC 中角色膨胀 | 数百个角色会变得难以管理 | 在复杂场景中改用 ABAC 或 ReBAC |
| 使用字符串比较令牌 | 时序攻击可逐个字符泄露令牌值 | 使用恒定时间比较(crypto.timingSafeEqual) |
| 没有令牌撤销策略 | 在 JWT 过期前无法使已泄露的 JWT 失效 | 设置较短的过期时间并使用刷新令牌,或维护阻止列表 |
CORS 设置为 credentials: true | Access-Control-Allow-Origin: * 不能与凭据一起使用 | 指定确切的源,并设置 Access-Control-Allow-Credentials: true |
SameSite=None 未搭配 Secure | 浏览器会静默拒绝 Cookie | 始终将 SameSite=None 与 Secure 标志搭配使用 |
| 刷新令牌重用时不检测 | 被盗的刷新令牌可授予无限期访问权限 | 轮换刷新令牌,并检测重用情况(令牌族) |
| 使用 OAuth2 Implicit 授权 | 令牌会暴露在 URL 片段中,且没有刷新令牌 | 改用 Authorization Code + PKCE(Implicit 已弃用) |
| 在 URL 或日志中放置密码 | URL 会被代理、浏览器和服务记录 | 始终在请求正文或标头中发送凭据 |
| 使用 Cookie 时缺少 CSRF 防护 | 基于 Cookie 的身份验证容易遭受跨站请求伪造 | 对会更改状态的操作使用 SameSite Cookie 和 CSRF 令牌 |
| 访问令牌有效期过长(数小时或数天) | 令牌泄露时攻击窗口很大 | 将访问令牌有效期控制在 5-15 分钟,并使用刷新令牌 |
| 以明文存储 API 密钥 | 数据库泄露会暴露所有密钥 | 对存储的密钥进行哈希处理(对密钥使用 SHA-256),并存储前缀以供查找 |
未验证 JWT aud 声明 | 面向 Service A 的令牌可能被 Service B 接受 | 始终验证 aud 是否与服务标识符匹配 |
| 会话固定 | 攻击者在登录前设置会话 ID,随后劫持会话 | 身份验证后重新生成会话 ID |
| 在代码中硬编码机密 | 机密会通过源代码管理泄露 | 使用环境变量或机密管理器(Vault、AWS SSM) |
| 信任身份感知代理提供的纯文本邮箱标头 | 在任何未经过代理的路径上,攻击者都能设置标头 | 验证代理签名的 JWT(签名 + 颁发者 + 受众);关闭所有绕过代理的路径 |
| 仅使用身份验证库中间件检查会话 | 框架中间件可能被绕过(Next.js CVE-2025-29927 类漏洞) | 在数据访问层或路由处理程序中重新检查会话 |
参考文件
| 文件 | 内容 | 行数 |
|---|---|---|
references/jwt-sessions.md | JWT 结构、签名、会话、Cookie、CSRF、存储 | ~650 |
references/oauth2-oidc.md | OAuth2 流程、OIDC、提供方集成、社交登录 | ~700 |
references/authorization.md | RBAC、ABAC、ReBAC、RLS、多租户、审计日志 | ~600 |
references/implementation.md | 密码哈希、多因素身份验证、速率限制、API 密钥、重置流程 | ~550 |
references/cloudflare-access.md | 通过 Cloudflare Access 实现的身份感知代理:应用/策略结构、令牌声明、JWT 验证、封闭源前提条件、服务身份验证、会话/登出/SPA、本地开发 | ~330 |
references/better-auth.md | Better Auth 库:服务端/客户端设置、适配器、会话模型、社交登录、插件目录(通行密钥/双因素身份验证/组织/SSO)、Hono 集成、迁移 | ~240 |
另请参阅
- security-ops - 更广泛的安全模式:OWASP、标头、输入验证、加密
- api-design-ops - API 设计,包括身份验证端点、速率限制
- postgres-ops - 用于数据库授权的行级安全性(RLS)策略
- cloudflare-ops - Access 前置源站背后的 Workers 运行时、wrangler 配置、机密和部署机制
评论
支持 Markdown