跳至內容
從 NextAuth.js v4 遷移?請閱讀 我們的遷移指南.
指南基於角色的存取控制

基於角色的存取控制

有兩種方法可以使用 Auth.js 將基於角色的存取控制 (RBAC)新增到您的應用程式,具體取決於您選擇的Session 策略。讓我們看看每個策略的範例。

取得角色

首先,將 profile() 回呼新增至提供者的設定,以判斷使用者角色

./auth.ts
import NextAuth from "next-auth"
import Google from "next-auth/providers/google"
 
export const { handlers, auth } = NextAuth({
  providers: [
    Google({
      profile(profile) {
        return { role: profile.role ?? "user", ... }
      },
    })
  ],
})
💡

判斷使用者角色是您的責任,您可以新增自己的邏輯,或者如果您的提供者傳回角色,您也可以改用該角色。

持久化角色

持久化角色會根據您使用的Session 策略而有所不同。如果您不知道自己使用的是哪種 Session 策略,那麼您很可能使用的是 JWT(預設策略)。

使用 JWT

當您沒有設定資料庫時,角色會透過使用 jwt() 回呼儲存在 Cookie 中。在登入時,role 屬性會從 user 物件的 profile 回呼中公開。將 user.role 值指派給 token.role 以持久化該值。就是這樣!

如果您也想在用戶端使用該角色,您可以透過 session 回呼公開它。

./auth.ts
import NextAuth from "next-auth"
import Google from "next-auth/providers/google"
 
export const { handlers, auth } = NextAuth({
  providers: [
    Google({
      profile(profile) {
        return { role: profile.role ?? "user", ... }
      },
    })
  ],
  callbacks: {
    jwt({ token, user }) {
      if(user) token.role = user.role
      return token
    },
    session({ session, token }) {
      session.user.role = token.role
      return session
    }
  }
})

使用此策略,如果您想要更新角色,則需要強制使用者再次登入。

使用資料庫

當您有資料庫時,您可以將使用者角色儲存在使用者模型中。以下範例顯示如何使用 Prisma 執行此操作,但其概念對於所有適配器都是相同的。

首先,將 role 欄新增至使用者模型。

/prisma/schema.prisma
model User {
  id            String    @id @default(cuid())
  name          String?
  email         String?   @unique
  emailVerified DateTime?
  image         String?
  role          String?  // New column
  accounts      Account[]
  sessions      Session[]
}

profile() 回呼的傳回值用於在資料庫中建立使用者。就是這樣!您新建立的使用者現在將具有已指派的角色。

如果您也想在用戶端使用該角色,您可以透過 session 回呼公開它。

./auth.ts
import NextAuth from "next-auth"
import Google from "next-auth/providers/google"
import prisma from "lib/prisma"
 
export const { handlers, auth } = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
    Google({
      profile(profile) {
        return { role: profile.role ?? "user", ... }
      }
    })
  ],
  callbacks: {
    session({ session, user }) {
      session.user.role = user.role
      return session
    }
  }
})

如何管理更新角色取決於您,可以透過直接資料庫存取或建立您的角色更新 API。

使用角色

使用者可以透過各自框架的設定檔匯出的授權函數存取目前 Session 中儲存的資訊。此函數會擷取透過設定檔中的 sessionjwt 回呼公開的資訊。利用此資訊,您可以實作不同的策略和邏輯,根據您的需求顯示 UI。

若要在伺服器端取得資料,您應該從設定檔匯入 auth 函數,並驗證使用者是否具有預期的角色。

./app/admin/page.tsx
import { auth } from "@/auth";
 
export default async function Page() {
  const session = await auth();
 
  if (session?.user?.role === "admin") {
    return <p>You are an admin, welcome!</p>;
  }
 
  return <p>You are not authorized to view this page!</p>;
}
💡

當使用 Next.js 和 JWT 時,您也可以選擇使用中介軟體,根據使用者的角色重新導向使用者,甚至在轉譯頁面之前。

資源

Auth.js © Balázs Orbán 和團隊 -2024