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

Next.js14 App Router配置Azure MSAL+next-auth单点登录指引

Next.js 14 App Router + NextAuth Azure MSAL 单点登录最简配置方案

1. 安装依赖

执行以下命令安装NextAuth:

npm install next-auth
# 或 yarn add next-auth
# 或 pnpm add next-auth

2. 配置环境变量

在项目根目录创建.env.local文件,填入Azure AD和NextAuth的配置信息:

# Azure AD 应用凭据
AZURE_AD_CLIENT_ID=你的Azure应用客户端ID
AZURE_AD_CLIENT_SECRET=你的Azure应用客户端密钥
AZURE_AD_TENANT_ID=你的租户ID(可填common/organizations或具体租户ID)

# NextAuth 基础配置
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=生成随机密钥(可通过`openssl rand -hex 32`命令生成)

3. 创建NextAuth API路由

App Router下需创建固定路径的API路由:src/app/api/auth/[...nextauth]/route.ts,内容如下:

import NextAuth from "next-auth";
import AzureADProvider from "next-auth/providers/azure-ad";

export const authOptions = {
  providers: [
    AzureADProvider({
      clientId: process.env.AZURE_AD_CLIENT_ID!,
      clientSecret: process.env.AZURE_AD_CLIENT_SECRET!,
      tenantId: process.env.AZURE_AD_TENANT_ID!,
      // 可选:自定义请求权限,默认包含openid profile email
      // scope: "openid profile email offline_access",
    }),
  ],
};

const handler = NextAuth(authOptions);

export { handler as GET, handler as POST };

4. 全局注入SessionProvider

修改根布局文件src/app/layout.tsx,用NextAuth的SessionProvider包裹整个应用,确保客户端组件能获取会话状态:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import { SessionProvider } from "next-auth/react";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Azure AD SSO Demo",
  description: "Next.js 14 App Router + NextAuth",
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="zh-CN">
      <body className={inter.className}>
        <SessionProvider>{children}</SessionProvider>
      </body>
    </html>
  );
}

5. 实现登录/登出组件

创建客户端组件src/app/components/AuthButtons.tsx,用于展示登录状态和操作:

"use client";

import { useSession, signIn, signOut } from "next-auth/react";

export default function AuthButtons() {
  const { data: session } = useSession();

  if (session) {
    return (
      <div>
        <p>当前登录用户:{session.user?.name}</p>
        <button onClick={() => signOut()}>登出</button>
      </div>
    );
  }

  return (
    <button onClick={() => signIn("azure-ad")}>使用Azure AD登录</button>
  );
}

在首页src/app/page.tsx中引入该组件:

import AuthButtons from "./components/AuthButtons";

export default function Home() {
  return (
    <main>
      <h1>Next.js 14 Azure AD SSO 演示</h1>
      <AuthButtons />
    </main>
  );
}

6. 保护路由(两种可选方案)

方案1:服务器组件直接校验会话

在需要保护的服务器组件(如src/app/protected/page.tsx)中,通过getServerSession校验会话,未登录则重定向:

import { getServerSession } from "next-auth/next";
import { authOptions } from "../api/auth/[...nextauth]/route";
import { redirect } from "next/navigation";

export default async function ProtectedPage() {
  const session = await getServerSession(authOptions);

  if (!session) {
    redirect("/api/auth/signin?callbackUrl=/protected");
  }

  return (
    <div>
      <h1>受保护页面</h1>
      <p>仅登录用户可访问</p>
      <p>用户详情:{JSON.stringify(session.user)}</p>
    </div>
  );
}

方案2:使用Middleware批量保护路由

创建src/middleware.ts文件,指定需要保护的路由规则,未登录用户会自动跳转至登录页:

export { default } from "next-auth/middleware";

export const config = {
  matcher: ["/protected/:path*", "/dashboard/:path*"], // 按需添加需要保护的路由
};

关键配置提示

  • Azure门户配置:注册Azure AD应用时,需将重定向URI设置为{你的域名}/api/auth/callback/azure-ad(本地开发为http://localhost:3000/api/auth/callback/azure-ad)
  • 生产环境注意:NEXTAUTH_URL需替换为实际域名,NEXTAUTH_SECRET必须设置,避免会话验证失败

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:40:18