背景介绍
在微服务架构中,我们经常需要处理多个子域名之间的用户认证问题。比如:
- main.example.com (主站)
- api.example.com (API服务)
- admin.example.com (管理后台)
很多开发者会选择自定义 Cookie 来实现跨域认证,但这种方式:
- 需要额外的 Cookie 配置
- 增加了维护成本
- 可能存在安全隐患
本文将介绍一个更优雅的解决方案。
核心思路
- 主站点使用 NextAuth.js 进行常规认证
其他域名服务器接收到主站 JWT 后,验证并生成新的 JWT
- 在 session 中携带新生成的 JWT
具体实现
1. 主站配置 (main.example.com)
..nextauth.ts
import NextAuth from 'next-auth'
export default NextAuth({
providers: [
// 你的认证提供者配置
],
callbacks: {
async session({ session, token }) {
// 在session中添加用户信息
session.user.id = token.sub
return session
}
}
})
2. API服务配置 (api.example.com)
session.ts1/1
import { getToken } from 'next-auth/jwt'
import jwt from 'jsonwebtoken'
export default async function handler(req, res) {
// 验证来自主站的token
const token = await getToken({ req })
if (!token) {
return res.status(401).json({ error: 'Unauthorized' })
}
// 生成新的JWT
const newToken = jwt.sign(
{
userId: token.sub,
scope: 'api-access'
},
process.env.JWT_SECRET,
{ expiresIn: '1h' }
)
// 将新token添加到session
const session = {
...token,
apiToken: newToken
}
res.json(session)
}
3. 前端调用示例
api.ts1/1
async function fetchWithAuth(url: string) {
// 获取主站session
const session = await getSession()
if (!session) {
throw new Error('Not authenticated')
}
// 获取API服务的token
const apiSession = await fetch('https://api.example.com/api/auth/session', {
headers: {
Authorization: `Bearer ${session.accessToken}`
}
}).then(res => res.json())
// 使用API token访问服务
return fetch(url, {
headers: {
Authorization: `Bearer ${apiSession.apiToken}`
}
})
}
方案优势
. 简单性
- 无需复杂的 Cookie 配置
- 遵循 JWT 标准流程
- 易于理解和维护
- 安全性
- 每个服务使用独立的 JWT
- 可以针对不同服务设置不同的权限范围
- 避免了 Cookie 相关的安全风险
- 灵活性
- 支持服务独立扩展
- 便于添加新的子域名服务
- 可以针对不同服务设置不同的过期时间
注意事项
- 确保各服务间的时钟同步
- 合理设置 JWT 过期时间
- 使用安全的密钥存储方式
- 在生产环境使用 HTTPS
总结
这种方案通过在 session 中携带新生成的 JWT,优雅地解决了多域名认证问题,避免了自定义 Cookie 带来的复杂性。它不仅简化了开发流程,还提供了更好的安全性和可维护性。
1206

被折叠的 条评论
为什么被折叠?



