Next.js 15 身份验证

2025-06-07

Next.js 15 身份验证

从 Next.js 15 开始,身份验证处理变得更加健壮和灵活,尤其是在其高级服务器组件、Actions API 和中间件功能的帮助下。在本文中,我们将探讨在 Next.js 15 应用程序中实现身份验证的最佳实践,涵盖服务器组件、中间件、Actions 和会话管理等基本主题。

目录

  1. Next.js 15 中的身份验证概述
  2. 设置身份验证
  3. 使用服务器组件进行身份验证
  4. 使用操作处理身份验证
  5. 实现 Auth Guard 中间件
  6. 会话管理和安全最佳实践
  7. 结论

Next.js 15 中的身份验证概述

Next.js 15 增强了服务器端渲染功能,并引入了用于处理身份验证的新工具,尤其是在服务器组件和 Actions API 的上下文中。使用服务器组件,您可以安全地在服务器上管理身份验证,而无需将敏感数据暴露给客户端,而 Actions API 则支持无缝的服务器通信。中间件可以帮助保护路由并动态检查用户权限,从而使身份验证流程更加安全且用户友好。


设置身份验证

首先,选择适合您应用的身份验证策略。常见方法包括:

  • JWT(JSON Web Tokens):适用于无状态应用程序,其中令牌存储在客户端上。
  • 基于会话的身份验证:适用于服务器上具有会话存储的应用程序。
  • OAuth:用于与第三方提供商(Google、GitHub 等)集成。

1. 安装next-auth身份验证

对于需要 OAuth 的应用程序,Next.js 可以很好地与之集成next-auth,从而简化会话和令牌管理。

npm install next-auth
Enter fullscreen mode Exit fullscreen mode

在 Next.js 15 设置中使用以下命令进行配置/app/api/auth/[...nextauth]/route.ts

// /app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";

export const authOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID!,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
    }),
  ],
  pages: {
    signIn: "/auth/signin",
  },
};

export default NextAuth(authOptions);
Enter fullscreen mode Exit fullscreen mode

使用服务器组件进行身份验证

在 Next.js 15 中,服务器组件允许您在服务器上渲染组件并安全地控制对数据的访问。

  1. 在服务器组件中获取用户会话:这减少了对客户端状态的依赖,并避免在客户端暴露敏感数据。您可以直接在服务器组件中获取用户会话数据。

  2. 服务器组件中的服务器端身份验证检查示例

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

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

     if (!session) {
       redirect("/auth/signin");
     }

     return (
       <div>
         <h1>Welcome, {session.user?.name}</h1>
       </div>
     );
   }
Enter fullscreen mode Exit fullscreen mode

这里,getServerSession安全地从服务器获取用户的会话数据。如果没有有效的会话,该redirect函数会将用户发送到登录页面。

使用操作处理身份验证

Next.js 15 中的 Actions API 提供了一种直接从客户端与服务器函数交互的方法。这对于登录、注销和注册操作尤其有用。

示例:创建登录操作

// /app/actions/loginAction.ts
"use server";

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

export const loginAction = async () => {
  const session = await getServerSession(authOptions);
  if (session) {
    return { user: session.user };
  } else {
    throw new Error("Authentication failed");
  }
};
Enter fullscreen mode Exit fullscreen mode

组件中登录操作的使用

// /app/components/LoginButton.tsx
"use client";

import { loginAction } from "../actions/loginAction";

export default function LoginButton() {
  const handleLogin = async () => {
    try {
      const user = await loginAction();
      console.log("User logged in:", user);
    } catch (error) {
      console.error("Login failed:", error);
    }
  };

  return <button onClick={handleLogin}>Log In</button>;
}
Enter fullscreen mode Exit fullscreen mode

安全地将其loginAction定义为服务器操作,并且客户端可以触发它而不会暴露敏感数据。

实现 Auth Guard 中间件

Next.js 15 中的中间件通过在加载页面之前验证服务器上的身份验证状态,提供了一种保护路由的强大方法。

路由保护中间件示例

为了保护/dashboard和等页面/profile,请在中创建中间件middleware.ts

// /middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const token = request.cookies.get("next-auth.session-token");
  const isAuthPage = request.nextUrl.pathname.startsWith("/auth");

  if (!token && !isAuthPage) {
    // Redirect to login if not authenticated
    return NextResponse.redirect(new URL("/auth/signin", request.url));
  }

  if (token && isAuthPage) {
    // Redirect to dashboard if authenticated and trying to access auth page
    return NextResponse.redirect(new URL("/dashboard", request.url));
  }

  return NextResponse.next();
}

// Apply middleware to specific routes
export const config = {
  matcher: ["/dashboard/:path*", "/profile/:path*", "/auth/:path*"],
};
Enter fullscreen mode Exit fullscreen mode

会话管理和安全最佳实践

在任何身份验证流程中,维护安全会话和保护用户数据都至关重要。

  1. 使用仅 HTTP Cookies 进行令牌存储

    • 避免将 JWT 存储在localStorage或 中sessionStorage。使用仅限 HTTP 的 Cookie 来防止 XSS 攻击。
  2. 会话到期和刷新令牌

    • 实施短期访问令牌和刷新令牌,以确保会话安全。您可以使用next-auth的会话管理功能来实现这一点。
  3. 基于角色的访问控制(RBAC)

    • 为用户分配角色,并根据其角色授权操作。在 中next-auth,可以使用会话对象或通过中间件和操作来完成此操作。
  4. 跨站请求伪造(CSRF)保护

    • 使用 CSRF 保护来阻止来自恶意站点的未经授权的请求。next-auth默认包含 CSRF 保护。
  5. 安全标头和 HTTPS

    • 始终通过 HTTPS 为您的应用程序提供服务并设置安全标头,如Content-Security-PolicyStrict-Transport-SecurityX-Frame-Options

结论

Next.js 15 带来了强大的工具和组件,用于安全地管理身份验证。利用服务器组件、操作和中间件,可以确保敏感数据在服务器上受到保护,并降低信息泄露给客户端的风险。

文章来源:https://dev.to/shieldstring/nextjs-15-authentication-1al7
PREV
Web 开发中的设计模式 - #2 Memento 简介 Memento 请少一些对话,多一些行动 设计模式 结语
NEXT
最被低估的浏览器功能和 API 有哪些?