NextAuth.js

NextAuth.js

1. Installation

npm install next-auth@beta

2. Authentication

3. Configuration

3.1 providers.authorize

执行时机:用户登陆时执行。

const authorize = (db: DB) => async (
  credentials: Record<"email" | "password", string> | undefined
) => {
  // 验证登录凭证
  const user = await db.user.findUnique({
    where: { email: credentials?.email }
  });
  
  if (!user || !credentials?.password) return null;
  
  const isValid = await bcrypt.compare(credentials.password, user.password);
  return isValid ? user : null;
}

3.2 callbacks.authorized

  • 执行时机:用户已登录后,访问受保护路由时执行。

  • 使用场景

    • 验证用户角色权限
    • 检查用户订阅状态
    • 实现基于路由的访问控制

如何配置受保护路由?

ℹ️
使用中间件,在项目的根目录下创建 middleware.ts 文件,并添加以下代码:
callbacks: {
  authorized: async ({ auth, request }) => {
    // 检查用户是否有权访问特定路由
    const path = request.nextUrl?.pathname;
    if (path?.startsWith('/admin')) {
      return auth?.user?.role === 'ADMIN';
    }
    return !!auth;
  }
}

4. Database

Models

User

Account

The Account model is for information about accounts associated with a User. A single User can have multiple Account(s), but each Account can only have one User.

For Example: use different OAuth providers to login, the account will be different.

Session

The Session model is used for database sessions and it can store arbitrary data for an active user session. A single User can have multiple Session(s), each Session can only have one User.

For Example: use different devices(app, web, etc.) to login, the session will be different.

VerificationToken

The VerificationToken model is used to store tokens for email-based magic-link sign in.

5. Session Management

Session Strategies

Auth.js supports 2 main session strategies, the JWT-based session and Database session.

optional strategy: "jwt" | "database";

5.3 Protecting Resources

Pages

Protecting routes can be done generally by checking for the session and taking an action if an active session is not found, like redirecting the user to the login page or simply returning a 401: Unauthenticated response.

API Routes

Next.js Middleware

With Next.js 12+, the easiest way to protect a set of pages is using the middleware file. You can create a middleware.ts file in your root pages directory with the following contents.

middleware.ts
export { auth as middleware } from "@/auth"

Then define authorized callback in your auth.ts file. For more details check out the reference docs.

auth.ts
import NextAuth from "next-auth"
 
export const { auth, handlers } = NextAuth({
  callbacks: {
    authorized: async ({ auth }) => {
      // Logged in users are authenticated, otherwise redirect to login page
      return !!auth
    },
  },
})

You can also use the auth method as a wrapper if you’d like to implement more logic inside the middleware.

middleware.ts
import { auth } from "@/auth"
 
export default auth((req) => {
  if (!req.auth && req.nextUrl.pathname !== "/login") {
    const newUrl = new URL("/login", req.nextUrl.origin)
    return Response.redirect(newUrl)
  }
})

You can also use a regex to match multiple routes or you can negate certain routes in order to protect all remaining routes. The following example avoids running the middleware on paths such as the favicon or static images.

middleware.ts
export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
}

Middleware will protect pages as defined by the matcher config export. For more details about the matcher, check out the Next.js docs.

6. Providers

6.1 GitHub,

6.2 Google

7. Adapters

7.1 Prisma

7.2 Drizzle

最后更新于