
























学习目标:为应用接入用户登录功能
随着现代Web应用的复杂性不断增加,用户认证和授权变得至关重要。NextAuth.js 是一个开源的用户认证库,支持多种身份验证方式,包括 OAuth、邮件登录、凭证登录等。它专为 Next.js 设计,但也可以集成到其他 React 应用中。通过其丰富的配置选项和内置的安全特性,开发者可以快速搭建一个功能强大的认证系统。
Provider 是 NextAuth.js 用于实现身份验证的核心,NextAuth.js 支持多种认证提供者,如 OAuth Providers:Google, Facebook, GitHub, Twitter 等第三方服务,Email Provider:基于邮箱的登录方式,以及 Credentials Provider:允许开发者自定义基于用户名和密码的登录系统。
NextAuth.js 支持两种 Session 管理策略,通过 JWT(JSON Web Token)或基于数据库的会话管理来保持用户的登录状态。JWT Session 为默认策略,本文的演示也给予默认策略。
NextAuth.js 支持无状态身份验证,使用 JWT 存储会话信息。
为了保存用户信息和会话数据,NextAuth.js 可以与各种数据库(如 MongoDB、PostgreSQL、MySQL)集成。
成功登录后,NextAuth 会在你的浏览器中设置一组 Cookies。
NextAuth.js 提供了多种回调函数,允许开发者在身份验证的不同阶段执行自定义逻辑。这些回调函数包括:
jwt:在生成或更新 JWT 时调用。session:在生成或更新会话时调用。signIn:在用户尝试登录时调用,可以控制是否允许登录。redirect:控制登录或注销后的重定向行为。提供了多种内置的安全机制,例如 CSRF 保护、JWT 加密,确保身份验证流程的安全性。
npx create-next-app@latest
✔ What is your project named? … example-auth
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias (@/*)? … No / Yes
首先需要安装 NextAuth.js 和相关依赖:
在集成 GitHub 登录之前,你需要创建一个 GitHub OAuth 应用来获取 Client ID 和 Client Secret。
http://localhost:3000(本地开发时使用)。http://localhost:3000/api/auth/callback/github(NextAuth.js 默认的 GitHub 回调 URL)。Client ID 和 Client Secret。在 app/api 目录下创建 auth/[...nextauth]/route.js 文件:
// app/api/auth/[...nextauth]/route.js
import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github";
const handler = NextAuth({
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
session: {
strategy: "jwt",
},
callbacks: {
async session({ session, token }) {
session.user.id = token.sub; // 将用户ID附加到会话中
return session;
},
},
});
export { handler as GET, handler as POST };
这个 API 路由将处理 GitHub 的 OAuth 身份验证过程。NextAuth.js 默认会处理 GET 和 POST 请求,因此需要导出 GET 和 POST 。
将 GitHub 应用的 Client ID 和 Client Secret 配置到 .env 文件中:
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
NEXTAUTH_URL=http://localhost:3000 # 本地开发时使用
确保用你从 GitHub 获取的 Client ID 和 Client Secret 替换相应的占位符。
NEXTAUTH_SECRET
#
你可以通过运行以下命令生成一个随机的 32 字节的密钥:
生成的密钥可能像这样:
base64encodedsecretstring==
将 NEXTAUTH_SECRET 配置到 .env 文件中:
NEXTAUTH_SECRET=base64encodedsecretstring==
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET,用于加密会话令牌(JWT)等。
useSession 管理会话
#
在 Next.js 13 中,使用 useSession 在页面或组件中显示用户的登录状态,并提供登录/注销按钮。
在 app/page.js 文件中,添加以下代码:
// app/page.js;
"use client";
import { useSession, signIn, signOut } from "next-auth/react";
export default function HomePage() {
const { data: session, status } = useSession();
if (status === "loading") {
return <p>Loading...</p>;
}
return (
<div className="p-10">
{!session ? (
<>
<p>Not signed in</p>
<button onClick={() => signIn("github")}>Sign in with GitHub</button>
</>
) : (
<>
<p>Signed in as {session.user.email}</p>
<img
className="w-[100px] h-[100px]"
src={session.user.image}
alt={session.user.name}
style={{ borderRadius: "50%" }}
/>
<button onClick={() => signOut()}>Sign out</button>
</>
)}
</div>
);
}
useSession 钩子获取当前用户的会话信息。next-auth 提供的 Provider
#
由于 App Router 是完全异步的,SessionProvider 必须包裹在根布局中。你需要在 app/layout.js 中配置 SessionProvider 以提供会话上下文。
app 目录创建 Provider.js:"use client";
import { SessionProvider } from "next-auth/react";
export function Provider({ children }) {
return <SessionProvider>{children}</SessionProvider>;
}
app/layout.js 文件中添加 Providers:// app/layout.js
import "./globals.css";
import { Provider } from "./Provider";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<Provider>{children}</Provider>
</body>
</html>
);
}
SessionProvider 确保会话信息可以在应用中的所有组件中访问。
最后,在终端中运行 Next.js 应用:
访问 http://localhost:3000,你会看到登录界面。点击 “Sign in with GitHub”,并使用 GitHub 账号进行登录。
你可以在 callbacks 选项中进一步自定义登录过程,比如获取用户的更多 GitHub 信息:
callbacks: {
async signIn({ user, account, profile }) {
return profile.email.endsWith("@example.com") // 仅允许特定域名的 GitHub 用户登录
},
async jwt({ token, account }) {
if (account) {
token.accessToken = account.access_token
}
return token
},
async session({ session, token }) {
session.accessToken = token.accessToken
return session
},
}
NextAuth.js 是一个功能强大且灵活的认证解决方案,适合各种规模的应用。从简单的 OAuth 集成到复杂的自定义认证逻辑,它几乎可以满足所有的需求。通过本文我们正式接入登录功能。
https://github.com/nextauthjs/next-auth
https://authjs.dev/concepts/session-strategies
https://next-auth.js.org/configuration/options#nextauth_secret
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。