NextAuth.js 实现多域名认证的最佳实践 - 无需自定义 Cookie

背景介绍

在微服务架构中,我们经常需要处理多个子域名之间的用户认证问题。比如:

  • 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 带来的复杂性。它不仅简化了开发流程,还提供了更好的安全性和可维护性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值