文章目录
- 一、常见登录鉴权方式概览
- 1.1 主流方案对比
- 1.2 技术特性对比
- 二、Session/Cookie方案
- 2.1 实现原理
- 2.2 代码实现
- 2.3 优缺点分析
- 三、JWT方案
- 3.1 实现原理
- 3.2 代码实现
- 3.3 优缺点分析
- 四、OAuth方案
- 4.1 实现原理
- 4.2 代码实现
- 4.3 优缺点分析
- 五、SSO方案
- 5.1 实现原理
- 5.2 代码实现
- 5.3 优缺点分析
- 六、安全增强方案
- 6.1 防御CSRF
- 6.2 防止重放攻击
- 七、生产环境最佳实践
- 7.1 安全配置
- 7.2 监控与报警
一、常见登录鉴权方式概览
1.1 主流方案对比
1.2 技术特性对比
方案 | 存储位置 | 安全性 | 扩展性 | 性能 | 适用场景 |
---|---|---|---|---|---|
Session/Cookie | 服务端 | 高 | 中 | 中 | 传统Web应用 |
JWT | 客户端 | 中 | 高 | 高 | 前后端分离 |
OAuth | 服务端 | 高 | 高 | 低 | 第三方登录 |
SSO | 服务端 | 高 | 高 | 中 | 企业级应用 |
二、Session/Cookie方案
2.1 实现原理
2.2 代码实现
// 服务端(Express示例)
app.post('/login', (req, res) => {
const { username, password } = req.body
const user = authenticate(username, password)
if (user) {
req.session.userId = user.id
res.json({ success: true })
} else {
res.status(401).json({ error: 'Invalid credentials' })
}
})
app.get('/profile', (req, res) => {
if (!req.session.userId) {
return res.status(401).json({ error: 'Unauthorized' })
}
const user = getUserById(req.session.userId)
res.json(user)
})
2.3 优缺点分析
优点:
- 安全性高:敏感信息存储在服务端
- 易于控制:可随时使Session失效
- 兼容性好:支持传统Web应用
缺点:
- 扩展性差:集群环境下需要Session共享
- 性能开销:每次请求都需要查询Session
- 跨域限制:Cookie存在SameSite限制
三、JWT方案
3.1 实现原理
3.2 代码实现
// JWT生成
function generateToken(user) {
return jwt.sign(
{ userId: user.id },
process.env.JWT_SECRET,
{ expiresIn: '1h' }
)
}
// 客户端存储
localStorage.setItem('token', token)
// 请求拦截
axios.interceptors.request.use(config => {
const token = localStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// 服务端验证
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization']
const token = authHeader && authHeader.split(' ')[1]
if (!token) return res.sendStatus(401)
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) return res.sendStatus(403)
req.user = user
next()
})
}
3.3 优缺点分析
优点:
- 无状态:服务端无需存储Session
- 扩展性好:适合分布式系统
- 性能高:减少数据库查询
- 跨域支持:不受Cookie限制
缺点:
- 安全性依赖实现:需妥善管理密钥
- 无法主动失效:依赖过期时间
- 信息泄露风险:Payload可解码
四、OAuth方案
4.1 实现原理
4.2 代码实现
// 客户端实现
function loginWithOAuth(provider) {
const authUrl = `${provider.authEndpoint}?client_id=${provider.clientId}&redirect_uri=${provider.redirectUri}&response_type=code&scope=email`
window.location.href = authUrl
}
// 处理回调
function handleOAuthCallback() {
const code = new URLSearchParams(window.location.search).get('code')
if (code) {
exchangeCodeForToken(code)
}
}
async function exchangeCodeForToken(code) {
const response = await fetch('/api/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ code })
})
const { access_token } = await response.json()
localStorage.setItem('oauth_token', access_token)
}
4.3 优缺点分析
优点:
- 安全性高:用户凭证不暴露给第三方
- 标准化:主流平台统一实现
- 权限控制:支持细粒度授权
- 用户体验:无需注册新账号
缺点:
- 实现复杂:涉及多个参与方
- 性能开销:多次跳转和请求
- 依赖第三方:服务稳定性不可控
五、SSO方案
5.1 实现原理
5.2 代码实现
// 认证中心
app.get('/sso/login', (req, res) => {
const { redirect_uri } = req.query
const token = generateToken()
res.redirect(`${redirect_uri}?token=${token}`)
})
// 应用A
app.get('/login', (req, res) => {
const redirectUri = encodeURIComponent('https://app-a.com/callback')
res.redirect(`https://sso.com/login?redirect_uri=${redirectUri}`)
})
app.get('/callback', (req, res) => {
const { token } = req.query
const user = verifyToken(token)
req.session.user = user
res.redirect('/')
})
5.3 优缺点分析
优点:
- 统一认证:一次登录,多处访问
- 集中管理:便于权限控制
- 安全性高:减少密码暴露
缺点:
- 实现复杂:需要统一认证中心
- 单点故障:认证中心宕机影响所有系统
- 性能开销:跨系统认证交互
六、安全增强方案
6.1 防御CSRF
// 服务端生成Token
app.use((req, res, next) => {
res.locals.csrfToken = generateCSRFToken()
next()
})
// 客户端验证
function validateCSRFToken(req) {
const clientToken = req.headers['x-csrf-token']
const serverToken = req.session.csrfToken
return clientToken === serverToken
}
6.2 防止重放攻击
function generateNonce() {
return crypto.randomBytes(16).toString('hex')
}
function validateNonce(nonce) {
if (usedNonces.has(nonce)) {
return false
}
usedNonces.add(nonce)
return true
}
七、生产环境最佳实践
7.1 安全配置
// Cookie安全设置
app.use(session({
secret: 'your-secret-key',
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 1000 * 60 * 60 * 24 // 1天
}
}))
7.2 监控与报警
// 登录失败监控
app.post('/login', (req, res) => {
const { username } = req.body
if (failedAttempts[username] > 5) {
sendAlert(`多次登录失败: ${username}`)
}
})
// 异常登录检测
function detectAnomaly(loginInfo) {
const { ip, device, location } = loginInfo
if (!previousLoginLocations[ip].includes(location)) {
sendAlert(`异常登录: ${ip} from ${location}`)
}
}
总结:本文详细讲解了主流登录鉴权方案的实现原理、代码示例和优缺点对比,并提供了安全增强和生产环境最佳实践。