首页 > web前端 > js教程 > 在 Next.js App Router 中使用 Auth.js 进行用户身份验证

在 Next.js App Router 中使用 Auth.js 进行用户身份验证

Susan Sarandon
发布: 2024-11-12 03:05:01
原创
690 人浏览过

目录

初始设置

  • 安装
  • 配置
    • NextAuthConfig 设置
    • 路由处理程序设置
    • 中间件
    • 在服务器端组件中获取会话
    • 在客户端组件中获取会话
  • 文件夹结构

实施身份验证:凭据和 Google OAuth

  • 设置 prisma
  • 凭证
  • 添加 Google OAuth 提供商
    • 设置 Google OAuth 应用程序
    • 设置重定向 URI
    • 设置环境变量
    • 设置提供商
  • 创建登录和注册页面
  • 文件夹结构

初始设置

安装

npm install next-auth@beta
登录后复制
登录后复制
// env.local
AUTH_SECRET=GENERATETD_RANDOM_VALUE
登录后复制
登录后复制

配置

NextAuthConfig 设置

// src/auth.ts
import NextAuth from "next-auth"

export const config = {
  providers: [],
}

export const { handlers, signIn, signOut, auth } = NextAuth(config)
登录后复制
登录后复制

它应该放在src文件夹内

Providers 在 Auth.js 中表示是可用于登录用户的服务。用户可以通过四种方式登录。

  • 使用内置的 OAuth 提供程序(例如 Github、Google 等...)
  • 使用自定义 OAuth 提供程序
  • 使用电子邮件
  • 使用凭证

https://authjs.dev/reference/nextjs#providers

路由处理程序设置

// src/app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers
登录后复制
登录后复制

此文件用于使用 Next.js App Router 设置路由处理程序。

中间件

// src/middleware.ts
import { auth } from "@/auth"

export default auth((req) => {
  // Add your logic here
}

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], //  It's default setting
}
登录后复制
登录后复制

在src文件夹内写入
如果写在 src 文件夹之外,中间件将无法工作。

中间件是一个允许您在请求完成之前运行代码的函数。它对于保护路由和处理整个应用程序的身份验证特别有用。

Matcher一个配置选项,用于指定哪些路由中间件应应用于。它有助于仅在必要的路由上运行中间件来优化性能
示例匹配器: ['/dashboard/:path*'] 仅将中间件应用于仪表板路由。

https://authjs.dev/getting-started/session-management/protecting?framework=express#nextjs-middleware

在服务器端组件中获取会话

// src/app/page.tsx
import { auth } from "@/auth"
import { redirect } from "next/navigation"

export default async function page() {
  const session = await auth()

  if (!session) {
    redirect('/login')
  }

  return (
    <div>
      <h1>Hello World!</h1>
      <img src={session.user.image} alt="User Avatar" />
    </div>
  )
}
登录后复制
登录后复制

在客户端组件中获取会话

// src/app/page.tsx
"use client"
import { useSession } from "next-auth/react"
import { useRouter } from "next/navigation"

export default async function page() {
  const { data: session } = useSession()
  const router = useRouter()

  if (!session.user) {
    router.push('/login')
  }

  return (
    <div>
      <h1>Hello World!</h1>
      <img src={session.user.image} alt="User Avatar" />
    </div>
  )
}

// src/app/layout.tsx
import type { Metadata } from "next";
import "./globals.css";
import { SessionProvider } from "next-auth/react"

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <SessionProvider>
          {children}
        </SessionProvider>
      </body>
    </html>
  );
}
登录后复制
登录后复制

文件夹结构

/src
  /app
    /api
      /auth
        [...nextauth]
          /route.ts  // Route Handler
    layout.tsx
    page.tsx

  auth.ts  // Provider, Callback, Logic etc
  middleware.ts  // A function before request
登录后复制
登录后复制

实施身份验证:凭据和 Google OAuth

设置棱镜

// prisma/schema.prisma

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  password      String?
  accounts      Account[]
  sessions      Session[]
}

model Account {
  // ... (standard Auth.js Account model)
}

model Session {
  // ... (standard Auth.js Session model)
}

// ... (other necessary models)

登录后复制
登录后复制
// src/lib/prisma.ts

import { PrismaClient } from "@prisma/client"

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }

export const prisma = globalForPrisma.prisma || new PrismaClient()

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma
登录后复制

证书

凭据,在身份验证上下文中,指的是使用用户提供的信息验证用户身份的方法,通常是用户名(或电子邮件)和密码。

我们可以在 src/auth.ts 中添加凭据。

npm install next-auth@beta
登录后复制
登录后复制

适配器:

  • 将身份验证系统连接到数据库或数据存储解决方案的模块。

秘密:

  • 这是一个随机字符串,用于哈希令牌、签名/加密 cookie 以及生成加密密钥。
  • 这对于安全至关重要,应该保密。
  • 在本例中,它是使用环境变量 AUTH_SECRET 设置的。

页面:

  • 此对象允许您自定义身份验证页面的 URL。
  • 在您的示例中,signIn: '/login' 表示登录页面将位于 '/login' 路由,而不是默认的 '/api/auth/signin'。

会话:

  • 这配置了会话的处理方式。
  • 策略:“jwt”表示 JSON Web Token 将用于会话管理而不是数据库会话。

回调:

  • 这些是在身份验证流程中的各个点调用的函数,允许您自定义流程。

jwt 回调:

  • 它在创建或更新 JWT 时运行。
  • 在您的代码中,它将用户信息(ID、电子邮件、姓名)添加到令牌中。

会话回调:

  • 每当检查会话时都会运行。
  • 您的代码正在将用户信息从令牌添加到会话对象。

添加 Google OAuth 提供商

设置 Google OAuth 应用程序

从 GCP Console 创建新的 OAuth 客户端 ID > API 和服务 >凭证

User Authentication with Auth.js in Next.js App Router

创建后,保存您的客户端 ID 和客户端密钥以供以后使用。

设置重定向 URI

当我们在本地工作时,设置http://localhost:3000/api/auth/callback/google

生产环境中,只需将 http://localhost:3000 替换为 https://-----即可。

User Authentication with Auth.js in Next.js App Router

设置环境变量

// env.local
AUTH_SECRET=GENERATETD_RANDOM_VALUE
登录后复制
登录后复制

设置提供商

// src/auth.ts
import NextAuth from "next-auth"

export const config = {
  providers: [],
}

export const { handlers, signIn, signOut, auth } = NextAuth(config)
登录后复制
登录后复制

https://authjs.dev/getting-started/authentication/oauth

创建登录和注册页面

// src/app/api/auth/[...nextauth]/route.ts
import { handlers } from "@/auth" // Referring to the auth.ts we just created
export const { GET, POST } = handlers
登录后复制
登录后复制
// src/middleware.ts
import { auth } from "@/auth"

export default auth((req) => {
  // Add your logic here
}

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"], //  It's default setting
}
登录后复制
登录后复制
// src/app/page.tsx
import { auth } from "@/auth"
import { redirect } from "next/navigation"

export default async function page() {
  const session = await auth()

  if (!session) {
    redirect('/login')
  }

  return (
    <div>
      <h1>Hello World!</h1>
      <img src={session.user.image} alt="User Avatar" />
    </div>
  )
}
登录后复制
登录后复制
// src/app/page.tsx
"use client"
import { useSession } from "next-auth/react"
import { useRouter } from "next/navigation"

export default async function page() {
  const { data: session } = useSession()
  const router = useRouter()

  if (!session.user) {
    router.push('/login')
  }

  return (
    <div>
      <h1>Hello World!</h1>
      <img src={session.user.image} alt="User Avatar" />
    </div>
  )
}

// src/app/layout.tsx
import type { Metadata } from "next";
import "./globals.css";
import { SessionProvider } from "next-auth/react"

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        <SessionProvider>
          {children}
        </SessionProvider>
      </body>
    </html>
  );
}
登录后复制
登录后复制
/src
  /app
    /api
      /auth
        [...nextauth]
          /route.ts  // Route Handler
    layout.tsx
    page.tsx

  auth.ts  // Provider, Callback, Logic etc
  middleware.ts  // A function before request
登录后复制
登录后复制

文件夹结构

// prisma/schema.prisma

model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  password      String?
  accounts      Account[]
  sessions      Session[]
}

model Account {
  // ... (standard Auth.js Account model)
}

model Session {
  // ... (standard Auth.js Session model)
}

// ... (other necessary models)

登录后复制
登录后复制

以上是在 Next.js App Router 中使用 Auth.js 进行用户身份验证的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板