我正在构建一个 nextjs 14 应用程序,该应用程序使用带有 src/app/.. 结构的应用程序路由器,使用layout.tsx 作为我的应用程序的入口点。
我没有许多文章中提到的页面文件夹或 _app.tsx。
为此,我想使用 Azure MSAL 配置进行单点登录
next-auth
我对文件夹结构和流程感到困惑,因为我找到的所有文章都到处都是,没有明确的示例。设置此文件夹结构和正确的文件夹结构的最佳或简单方法是什么?
我尝试遵循 nextjs、next-auth 和 azure 的文档,但没有什么是清晰和端到端的。我对项目结构更加困惑,因为大多数文章建议使用页面文件夹或 _app.tsx 或react-msal 配置方式
我尝试使用 App Router 和 next-auth 来设置 Azure MSAL SSO 身份验证的以下 Next.js 应用程序。
请参阅我的 GitHub 存储库 以获取完整代码。
完整的项目结构:
代码:
src/app/api/auth/[...nextauth]/route.ts:
以下代码将 next-auth 配置为使用 Azure AD 进行用户身份验证、管理令牌和会话详细信息,并确保使用必要的 Azure AD 凭据正确配置环境。
import NextAuth from "next-auth";
import AzureADProvider from "next-auth/providers/azure-ad";
const { AZURE_AD_CLIENT_ID, AZURE_AD_CLIENT_SECRET, AZURE_AD_TENANT_ID } =
process.env;
if (!AZURE_AD_CLIENT_ID || !AZURE_AD_CLIENT_SECRET || !AZURE_AD_TENANT_ID) {
throw new Error("The Azure AD environment variables are not set.");
}
const handler = NextAuth({
secret: AZURE_AD_CLIENT_SECRET,
providers: [
AzureADProvider({
clientId: AZURE_AD_CLIENT_ID,
clientSecret: AZURE_AD_CLIENT_SECRET,
tenantId: AZURE_AD_TENANT_ID,
}),
],
callbacks: {
async jwt({ token, account }) {
if (account) {
token = Object.assign({}, token, {
access_token: account.access_token,
});
}
return token;
},
async session({ session, token }) {
if (session) {
session = Object.assign({}, session, {
access_token: token.access_token,
});
console.log(session);
}
return session;
},
},
});
export { handler as GET, handler as POST };
类型/next-auth.d.ts:
import NextAuth from "next-auth";
declare module "next-auth" {
interface Session {
access_token?: string;
}
}
src/app/page.tsx:
import React from 'react';
const HomePage = () => {
return (
<div>
<h1>Welcome to the Home Page</h1>
<a href="/api/auth/signin">Login</a>
</div>
);
};
export default HomePage;
src/app/components/Header.tsx:
Header
组件提供了一个用于管理身份验证状态的用户界面,包括在用户登录时显示欢迎消息并提供注销按钮,同时适当处理加载状态。
"use client";
import React from "react";
import { signOut, useSession } from "next-auth/react";
const Header = () => {
const { data: session, status } = useSession();
const handleLogOutClick = async () => {
try {
await signOut();
} catch (error) {
console.error(error);
}
};
if (status === 'loading') {
return <div>Loading...</div>;
}
return (
<header>
{session ? (
<>
<p>Welcome, {session.user?.email || "User"}</p>
<button onClick={handleLogOutClick}>Logout</button>
</>
) : (
<p>You are not logged in</p>
)}
</header>
);
};
export default Header;
.env.local:
AZURE_AD_CLIENT_ID=<clienyID>
AZURE_AD_CLIENT_SECRET=<clientSecret>
AZURE_AD_TENANT_ID=<tenantID>
NEXTAUTH_URL=http://localhost:3000
我在应用程序注册>身份验证>Web重定向URI中添加了以下URL,如下所示,
http://localhost:3000/api/auth/callback/azure-ad
输出:
我使用“登录”和“注销”按钮成功登录和退出。
参考:@Seeker 的SO回答。