You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13(App目录)结合Laravel Sanctum的认证及Token存储问题

解决思路:Next.js 13 + Laravel Sanctum 会话与Token管理

一、Token存储的两种实用方案

1. HttpOnly Cookie(优先选,贴合Sanctum设计)

Laravel Sanctum本身就是靠Cookie维护会话的,完全不用手动存Token,浏览器会自动处理。

操作要点:

  • 后端配置:
    打开config/cors.php,把supports_credentials设为true,allowed_origins添加你的Next.js域名(比如http://localhost:3000)。
    打开config/sanctum.php,在stateful数组里加入Next.js域名。
  • 前端请求必须带credentials: 'include',示例:
const login = async (email, password) => {
  const res = await fetch('http://你的Laravel接口域名/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include', // 关键,让浏览器自动携带Cookie
    body: JSON.stringify({ email, password })
  });
  const data = await res.json();
  // 登录成功后,所有后续请求都加这个参数,不用管Token的事
};

这种方式最安全,HttpOnly Cookie没法被JS读取,能防XSS攻击。

2. LocalStorage(简单但风险高)

如果一定要手动存Token,让后端登录接口返回Bearer Token,前端存在LocalStorage里,之后请求时在Header里带上。

示例:

// 登录时存Token
const login = async (email, password) => {
  const res = await fetch('http://你的Laravel接口域名/login', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, password })
  });
  const { token } = await res.json();
  localStorage.setItem('sanctum-token', token);
};

// 后续请求带Token
const fetchProducts = async () => {
  const token = localStorage.getItem('sanctum-token');
  const res = await fetch('http://你的Laravel接口域名/products', {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  return res.json();
};

⚠️ 注意:LocalStorage容易被XSS攻击窃取Token,生产环境尽量不用。

二、NextAuth的适配方案

完全可以用NextAuth来管理登录流程,把Laravel Sanctum作为自定义数据源,NextAuth帮你处理会话状态、路由守卫这些琐事。

1. 用Credentials Provider对接

NextAuth的Credentials Provider允许你自定义登录逻辑,直接调用Laravel的登录接口,把Sanctum Token存在NextAuth的会话里。

操作步骤:

  • 先装NextAuth:npm install next-auth
  • 在app/api/auth/[...nextauth]/route.js写配置:
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';

export const authOptions = {
  providers: [
    CredentialsProvider({
      name: '账号密码登录',
      credentials: {
        email: { label: '邮箱', type: 'email' },
        password: { label: '密码', type: 'password' }
      },
      async authorize(credentials) {
        // 调用Laravel登录接口
        const res = await fetch('http://你的Laravel接口域名/login', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            email: credentials.email,
            password: credentials.password
          })
        });
        const user = await res.json();
        
        // 登录成功就返回用户信息和Token,NextAuth会存到会话里
        if (res.ok && user.token) {
          return { ...user, token: user.token };
        }
        return null;
      }
    })
  ],
  session: {
    strategy: 'jwt', // 用JWT存会话,适配自定义Token
  },
  callbacks: {
    async jwt({ token, user }) {
      // 登录时把Sanctum Token加到JWT里
      if (user) {
        token.sanctumToken = user.token;
      }
      return token;
    },
    async session({ session, token }) {
      // 把Token暴露给前端会话,方便请求用
      session.user.sanctumToken = token.sanctumToken;
      return session;
    }
  }
};

const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
  • 前端用useSession拿Token,然后请求接口:
import { useSession } from 'next-auth/react';

const fetchOrders = async () => {
  const { data: session } = useSession();
  if (!session) return [];
  
  const res = await fetch('http://你的Laravel接口域名/orders', {
    headers: { 'Authorization': `Bearer ${session.user.sanctumToken}` }
  });
  return res.json();
};

2. 结合Sanctum Cookie和NextAuth

如果用Sanctum的Cookie方案,NextAuth可以用来做前端的状态管理(比如判断用户是否登录、路由拦截),实际API请求还是靠浏览器自动带Cookie。

这种情况下,authorize逻辑改成验证Cookie是否有效:

async authorize(credentials) {
  // 调用Laravel的用户信息接口,验证Cookie有效性
  const res = await fetch('http://你的Laravel接口域名/api/user', {
    credentials: 'include'
  });
  if (res.ok) {
    const user = await res.json();
    return user;
  }
  return null;
}

这样NextAuth负责前端的会话状态,后端还是用Sanctum的Cookie机制,两全其美。

三、关键注意事项

  • 跨域配置必须正确:Laravel的CORS和Sanctum的stateful域名必须包含你的Next.js域名,否则Cookie传不过去。
  • 用NextAuth的话,一定要在环境变量里设NEXTAUTH_URL,指向你的Next.js域名。
  • 生产环境必须用HTTPS,防止Token被明文劫持。

内容的提问来源于stack exchange,提问作者psudo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 07:00:17