ロールベースアクセス制御
Auth.jsを使用して、ロールベースアクセス制御(RBAC)をアプリケーションに追加する方法は、選択したセッション戦略に基づいて2つあります。それぞれの例を見てみましょう。
ロールを取得する
まず、ユーザーロールを決定するために、プロバイダーの構成にprofile()
コールバックを追加します。
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", ... }
},
})
],
})
ユーザーのロールを決定するのはあなたの責任です。独自のロジックを追加するか、プロバイダーがロールを返す場合は代わりにそれを使用できます。
ロールを永続化する
ロールの永続化は、使用しているセッション戦略によって異なります。使用しているセッション戦略がわからない場合は、おそらくJWT(デフォルト)を使用しています。
JWTを使用する
データベースが構成されていない場合、jwt()
コールバックを使用することにより、ロールはCookieに永続化されます。サインイン時に、role
プロパティは、user
オブジェクトのprofile
コールバックから公開されます。user.role
値をtoken.role
に割り当てることで永続化します。以上です!
クライアントでロールを使用したい場合は、session
コールバックを介してロールを公開できます。
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
}
}
})
この戦略では、ロールを更新したい場合は、ユーザーに再度サインインを強制する必要があります。
データベースを使用する
データベースがある場合は、Userモデルにユーザーロールを保存できます。以下の例は、Prismaでこれを行う方法を示していますが、考え方はすべてのアダプターで同じです。
まず、role
列をUserモデルに追加します。
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
コールバックを介してロールを公開できます。
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
およびjwt
コールバックを介して公開された情報を取得します。この情報を使用して、ニーズに基づいてUIを表示するためのさまざまな戦略とロジックを実装できます。
サーバー側でデータを取得するには、構成ファイルからauth
関数をインポートし、ユーザーが予期されたロールを持っているかどうかを確認する必要があります。
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を使用している場合は、Middlewareを使用して、ページをレンダリングする前でも、ロールに基づいてユーザーをリダイレクトすることもできます。