这是一篇关于在 Next.js 14 中使用 NextAuth v5(beta版)的实践教程。由于 NextAuth v5 还处于 beta 阶段,相关文档和资料比较少。本文结合了 Next.js 14 官方文档以及实际开发经验。

一、环境搭建

1. 创建项目

使用以下命令创建一个新的 Next.js 项目:

npx create-next-app@latest

本项目采用以下技术栈:

  • TypeScript
  • Tailwind CSS
  • src/ 目录结构
  • App Router 路由方案

2. 安装依赖

安装 NextAuth beta 版:

npm install next-auth@beta

确保 package.json 中的版本号不低于 ^5.0.0-beta.4

3. 生成密钥

使用 openssl 生成认证密钥:

openssl rand -base64 32

⚠️ 注意: 该密钥需要妥善保管,不要提交到代码仓库中

4. 配置环境变量

创建 .env 文件并添加认证密钥:

# .env
AUTH_SECRET=你的密钥

记得将 .env 添加到 .gitignore 中。

二、项目结构

image.png

在基础的 Next.js 项目中需要新增以下文件:

src/
  ├── app/
  │   └── login/        # 登录页面
  ├── lib/             # 工具函数
  ├── auth.config.ts   # 认证配置
  ├── auth.ts          # NextAuth 配置
  └── middleware.ts    # 中间件配置

三、主要页面实现

Login 页面

// src/app/login/page.tsx
"use client"

export default function Page() {
  return (
    <div>
      <h1>Log in Page</h1>
      <form className="flex flex-col">
        <input className="bg-blue-300 text-black" name="id" />
        <input 
          className="bg-yellow-300 text-black" 
          name="password" 
          type="password"
        />
        <button>Log In</button>
      </form>
    </div>
  )
}

Home 页面

// src/app/page.tsx
export default async function Home() {
  return (
    <div>
      <h1>Home Page</h1>
      <h2>Unavailable without auth</h2>
      <form>
        <button>Log Out</button>
      </form>
    </div>
  )
}

使用npx next dev或npm run dev或 yarn 运行应用程序。

http://localhost:3000/login

image.png

http://localhost:3000/

image.png

四、权限认证配置

1. 用户类型定义

// src/lib/definitions.ts
export type User = {
    id: string
    email: string
    name: string
};

2. 认证配置

// src/auth.config.ts
import type { NextAuthConfig } from 'next-auth';

export const authConfig = {
  pages: {
    signIn: '/login',
  },
  callbacks: {
    authorized({ auth, request: { nextUrl } }) {
      const isLoggedIn = !!auth?.user;
      const isOnProtected = !nextUrl.pathname.startsWith('/login');
      
      if (isOnProtected) {
        if (isLoggedIn) return true;
        return false; // 重定向到登录页
      } else if (isLoggedIn) {
        return Response.redirect(new URL('/', nextUrl));
      }
      return true;
    },
  },
  providers: [], 
};

3. NextAuth 初始化

// src/auth.ts
import NextAuth from 'next-auth';
import { authConfig } from './auth.config';
import Credentials from 'next-auth/providers/credentials';

export const { signIn, signOut } = NextAuth({
  ...authConfig,
  providers: [
    Credentials({
      async authorize(credentials) {
        if (credentials.id && credentials.password) {
          // 这里添加实际的登录逻辑
          let loginRes = {
            success: true,
            data: {
              user: {
                ID: "john_doe",
                NAME: "John Doe", 
                EMAIL: "email@email.email",
              },
            }
          }
          if (!loginRes.success) return null;
          
          return {
            id: loginRes.data.user.ID,
            name: loginRes.data.user.NAME,
            email: loginRes.data.user.EMAIL,
          };
        }
        return null;
      },
    })
  ],
  callbacks: {
    async session({ session, token }) {
      session.user = token.user as User;
      return session;
    },
    async jwt({ token, user }) {
      if (user) {
        token.user = user;
      }
      return token;
    },
  },
});

4. 中间件配置

// src/middleware.ts
import NextAuth from 'next-auth';
import { authConfig } from './auth.config';

export default NextAuth(authConfig).auth;

export const config = {
  matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],
};

5. 结果

在未登录的情况下前往http://localhost:3000/

image.png

我们被重定向到登录页面。然后随便输入:

image.png

然后点击 "登录 "按钮

image.png

五、部署注意事项

部署前需要在 .env 中配置以下环境变量:

NEXTAUTH_URL=${部署域名}
NEXT_PUBLIC_API_URL=${部署域名}

⚠️ 如果不配置这些变量,回调 URL 会默认使用 localhost:3000 导致报错。

以上就是在 Next.js 14 中集成 NextAuth v5 的完整实现流程。目前示例中使用了硬编码的用户数据,实际项目中需要根据后端 API 修改登录逻辑和用户类型定义。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试完整考点、资料以及我的系列文章。

王大冶
68k 声望104.9k 粉丝