寻求Next.js v13.4 AppRouter下Laravel Breeze API与NextAuth.js集成方案
Laravel Breeze API + Next.js 13.4+ App Router + NextAuth.js 集成指南
环境准备
- Laravel 10+ 并完成 Breeze API 安装
- Next.js 13.4+(启用 App Router)
- Node.js 18+
Laravel Breeze API 配置
- 安装 Breeze API:
composer require laravel/breeze --dev php artisan breeze:install api - 配置 CORS:修改
config/cors.phppaths添加/api/*allowed_origins设为你的 Next.js 域名(如http://localhost:3000)supports_credentials设为true
- 配置 Sanctum:
修改php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"config/sanctum.php的stateful数组,加入你的 Next.js 域名 - 测试登录接口:发送
POST /api/login请求,确认返回包含token和user的响应
Next.js 端配置
1. 安装依赖
npm install next-auth axios
2. 创建 NextAuth 配置文件
新建app/api/auth/[...nextauth]/route.ts:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import axios from "axios"; export const authOptions = { providers: [ CredentialsProvider({ name: "Credentials", credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" }, }, async authorize(credentials) { if (!credentials?.email || !credentials?.password) return null; try { const res = await axios.post( `${process.env.NEXT_PUBLIC_LARAVEL_API_URL}/api/login`, { email: credentials.email, password: credentials.password }, { withCredentials: true } ); return res.data.user ? { ...res.data.user, token: res.data.token } : null; } catch (err) { console.error(err); return null; } }, }), ], session: { strategy: "jwt" }, callbacks: { async jwt({ token, user }) { if (user) { token.user = user; token.accessToken = user.token; } return token; }, async session({ session, token }) { session.user = token.user as any; session.accessToken = token.accessToken as string; return session; }, }, pages: { signIn: "/login" }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
3. 配置环境变量
在.env.local中添加:
NEXT_PUBLIC_LARAVEL_API_URL=http://localhost:8000 NEXTAUTH_SECRET=your-nextauth-secret-here # 用命令生成:openssl rand -hex 32 NEXTAUTH_URL=http://localhost:3000
4. App Router 中使用 Auth
客户端组件:登录页面(app/login/page.tsx)
"use client"; import { useState } from "react"; import { signIn } from "next-auth/react"; import { useRouter } from "next/navigation"; export default function LoginPage() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const router = useRouter(); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); const result = await signIn("credentials", { email, password, redirect: false }); result?.ok ? router.push("/dashboard") : alert("登录失败,请检查账号密码"); }; return ( <div className="max-w-md mx-auto mt-10"> <form onSubmit={handleSubmit} className="space-y-4"> <div> <label>邮箱</label> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} className="w-full p-2 border rounded" required /> </div> <div> <label>密码</label> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} className="w-full p-2 border rounded" required /> </div> <button type="submit" className="w-full p-2 bg-blue-500 text-white rounded"> 登录 </button> </form> </div> ); }
服务端组件:受保护的仪表盘(app/dashboard/page.tsx)
import { getServerSession } from "next-auth/next"; import { authOptions } from "../api/auth/[...nextauth]/route"; import axios from "axios"; import { redirect } from "next/navigation"; export default async function DashboardPage() { const session = await getServerSession(authOptions); if (!session) redirect("/login"); // 服务端请求 Laravel API 获取用户数据 const userRes = await axios.get( `${process.env.NEXT_PUBLIC_LARAVEL_API_URL}/api/user`, { headers: { Authorization: `Bearer ${session.accessToken}` }, withCredentials: true, } ); return ( <div className="max-w-md mx-auto mt-10"> <h1 className="text-xl font-bold">仪表盘</h1> <p className="mt-4">欢迎回来,{userRes.data.name}!</p> </div> ); }
客户端组件:用户信息展示(app/components/UserInfo.tsx)
"use client"; import { useSession } from "next-auth/react"; export default function UserInfo() { const { data: session } = useSession(); return session ? <p>当前用户:{session.user.email}</p> : <p>未登录</p>; }
登出功能(客户端组件)
"use client"; import { signOut } from "next-auth/react"; export function LogoutButton() { return ( <button onClick={() => signOut({ redirect: true, callbackUrl: "/login" })} className="text-blue-500 ml-4" > 登出 </button> ); }
测试验证
- 启动 Laravel 服务:
php artisan serve - 启动 Next.js 服务:
npm run dev - 访问
http://localhost:3000/login,用 Laravel 后台创建的用户登录,验证跳转逻辑 - 进入仪表盘,确认能正常获取用户数据
- 点击登出,验证是否回到登录页
内容的提问来源于stack exchange,提问作者karmendra
相关产品推荐
相关产品推荐

