跳到主要内容

认证与授权速查表

本文档提供认证与授权常用协议、代码片段及安全配置的快速参考。

认证协议选择指南

协议适用场景核心特点
Session-Cookie单体 Web 应用、管理后台服务端存储状态、安全性高、实现简单
JWT微服务、移动端、无状态 API客户端存状态、易扩展、需处理令牌撤销
OAuth 2.1第三方登录、API 授权行业标准、必须使用 PKCE、支持多种客户端
OIDC身份识别、SSO、统一身份基于 OAuth 2.0、标准化用户信息(ID Token)
SAML 2.0企业传统应用、HR/ERPXML 断言、强审计能力、配置复杂

JWT 快速参考

结构

header.payload.signature

Header 示例

{
"alg": "RS256",
"typ": "JWT"
}

常用声明 (Claims)

声明含义说明
issIssuer签发者
subSubject主题(通常是用户 ID)
audAudience接收方
expExpiration过期时间(Unix 时间戳)
iatIssued At签发时间
nbfNot Before生效时间
jtiJWT ID唯一标识

签名算法

算法类型适用场景
HS256对称(HMAC)单服务、简单场景
RS256非对称(RSA)微服务、推荐生产使用
ES256非对称(ECDSA)高性能场景

Node.js 代码

const jwt = require('jsonwebtoken');

// 签发
const token = jwt.sign(
{ sub: 'user_123', role: 'admin' },
process.env.JWT_SECRET,
{ expiresIn: '15m', algorithm: 'RS256' }
);

// 验证
try {
const payload = jwt.verify(token, publicKey, { algorithms: ['RS256'] });
} catch (err) {
// TokenExpiredError | JsonWebTokenError | NotBeforeError
}

Python 代码

import jwt

# 签发
token = jwt.encode(
{'sub': 'user_123', 'role': 'admin'},
SECRET_KEY,
algorithm='HS256',
headers={'exp': datetime.utcnow() + timedelta(minutes=15)}
)

# 验证
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
except jwt.ExpiredSignatureError:
pass
except jwt.InvalidTokenError:
pass

安全检查清单

  • 明确指定允许的算法(algorithms 参数)
  • 验证 exp 声明
  • 验证 iss 签发者
  • 验证 aud 受众
  • 使用足够长度的密钥(≥256 位)
  • 敏感数据不放入载荷
  • Access Token 有效期不超过 1 小时
  • 实现 Refresh Token 机制

OAuth 2.1 快速参考

授权码模式流程

1. GET /authorize?response_type=code&client_id=ID&redirect_uri=URI&scope=openid&state=xyz&code_challenge=HASH&code_challenge_method=S256

2. 用户授权后重定向:redirect_uri?code=AUTH_CODE&state=xyz

3. POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=CODE&redirect_uri=URI&client_id=ID&code_verifier=ORIGINAL

常用 Scope

Scope含义
openidOIDC 身份认证
profile用户基本信息
email用户邮箱
offline_access获取 Refresh Token

PKCE 代码

// 生成 code_verifier
const codeVerifier = crypto.randomBytes(32).toString('base64url');

// 计算 code_challenge
const codeChallenge = crypto
.createHash('sha256')
.update(codeVerifier)
.digest('base64url');

State 参数验证

import secrets

# 发起授权请求
state = secrets.token_urlsafe(32)
session['oauth_state'] = state

# 验证回调
if request.args.get('state') != session.pop('oauth_state'):
raise SecurityError('Invalid state')

推荐配置

Set-Cookie: sessionId=abc123; 
HttpOnly;
Secure;
SameSite=Lax;
Path=/;
Max-Age=3600;
Domain=example.com

属性说明

属性说明
HttpOnly禁止 JavaScript 访问,防 XSS
Secure仅 HTTPS 传输
SameSite=Strict仅同站请求携带
SameSite=Lax导航到目标站点的 GET 请求携带(推荐)
SameSite=None允许跨站(必须配合 Secure)

密码哈希

推荐算法

算法特点推荐度
Argon2id抗 GPU 攻击、内存硬化★★★★★
bcrypt主流选择、计算成本可调★★★★☆
scrypt内存硬化★★★★☆
PBKDF2兼容性好、可定制迭代次数★★★☆☆

禁止使用

  • MD5、SHA-1、SHA-256 等快速哈希
  • 明文存储

Argon2 示例

import argon2

ph = argon2.PasswordHasher()

# 哈希
hashed = ph.hash("password123")

# 验证
try:
ph.verify(hashed, "password123")
except argon2.exceptions.VerifyMismatchError:
print("密码错误")

bcrypt 示例

const bcrypt = require('bcrypt');

// 哈希(cost factor: 12)
const hash = await bcrypt.hash('password123', 12);

// 验证
const match = await bcrypt.compare('password123', hash);

HTTP 安全头

完整配置

# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;

# 强制 HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;

# 内容安全策略
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:;" always;

# 禁用 MIME 嗅探
add_header X-Content-Type-Options "nosniff" always;

# XSS 保护
add_header X-XSS-Protection "1; mode=block" always;

# Referrer 策略
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# 权限策略
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

权限模型对比

模型核心概念适用场景
RBAC用户 → 角色 → 权限组织结构清晰、权限稳定
ABAC属性 + 策略 → 决策动态决策、零信任架构
ReBAC实体关系 → 权限社交网络、协作工具
ACL资源 → 用户列表简单场景、文件系统

RBAC 数据库设计

-- 核心表
users(id, username, email)
roles(id, name, description)
permissions(id, resource, action)
user_roles(user_id, role_id)
role_permissions(role_id, permission_id)

RBAC 权限检查

// 检查权限
async function hasPermission(userId, resource, action) {
const query = `
SELECT 1 FROM permissions p
JOIN role_permissions rp ON p.id = rp.permission_id
JOIN user_roles ur ON rp.role_id = ur.role_id
WHERE ur.user_id = ? AND p.resource = ? AND p.action = ?
`;
return (await db.query(query, [userId, resource, action])).length > 0;
}

MFA 方式对比

方式安全性便捷性成本推荐
TOTP★★★★★
Passkeys最高★★★★★
短信验证码★★★☆☆
邮箱验证码★★★☆☆
硬件密钥最高★★★★☆

TOTP 生成

import pyotp

# 生成密钥
secret = pyotp.random_base32()

# 生成 otpauth URL
uri = pyotp.totp.TOTP(secret).provisioning_uri(
name='[email protected]',
issuer_name='MyApp'
)

# 验证
totp = pyotp.TOTP(secret)
is_valid = totp.verify(user_input)

密码安全快速参考

密码哈希算法选择

算法内存硬度GPU 抵抗推荐度
Argon2id★★★★★
bcrypt★★★★☆
scrypt★★★★☆
PBKDF2★★★☆☆
SHA/MD5✗ 禁止

密码策略(NIST SP 800-63B)

场景最小长度推荐最大长度
启用 MFA8 字符至少 64 字符
未启用 MFA15 字符至少 64 字符

密码安全检查清单

  • 使用 Argon2id 或 bcrypt 存储密码
  • 禁止明文存储和通用哈希(SHA/MD5)
  • 检查密码是否在已知泄露数据库中
  • 不强制要求复杂度规则(大小写、数字、符号)
  • 允许所有可打印字符(包括空格和 Unicode)
  • 使用密码强度评估工具(如 zxcvbn)
  • 不强制定期更改密码(除非泄露)
  • 登录成功后重新生成会话 ID

密码重置安全要点

  • 令牌足够长(≥32 字节),使用加密安全随机数
  • 令牌有效期短(15-30 分钟)
  • 存储令牌的哈希值,不存原文
  • 使用后立即失效
  • 防止用户枚举(统一响应)
  • 重置后使所有现有会话失效

常见安全攻击防御

攻击类型核心防御
暴力破解账户锁定、速率限制、CAPTCHA、MFA
撞库攻击泄露检测、IP 信誉、MFA
密码喷洒全局速率限制、IP 限制
会话劫持安全 Cookie、会话绑定、HTTPS
会话固定登录后重新生成会话 ID
CSRFSameSite Cookie + CSRF Token
重放攻击Nonce、时间戳验证
JWT 攻击算法白名单、密钥分离

常见安全漏洞检查

漏洞检查点防御方案
会话劫持Cookie 是否设了 HttpOnly?启用 HttpOnly
会话固定登录后是否更换 Session ID?登录后 regenerate()
CSRFPOST 请求是否验证 Token?SameSite=Lax + CSRF Token
XSS是否转义用户输入?CSP + 输出编码
JWT 注入是否信任 alg: none?硬编码只接受 RS256/HS256
密钥泄露密钥是否硬编码?环境变量或密钥管理服务
SQL 注入是否拼接 SQL?使用参数化查询
弱密码是否有密码强度要求?强制密码策略

错误码速查

HTTP 状态码含义
401 Unauthorized未认证
403 Forbidden已认证但无权限
400 Bad Request请求格式错误
409 Conflict资源冲突(如用户名已存在)

常用身份提供商

提供商协议支持适用场景
Auth0OAuth 2.0, OIDC, SAML企业应用、CIAM
OktaOAuth 2.0, OIDC, SAML企业 SSO
Azure ADOAuth 2.0, OIDC, SAMLMicrosoft 生态
KeycloakOAuth 2.0, OIDC, SAML开源自托管
Firebase AuthOAuth 2.0, OIDC移动应用、快速开发

参考资料