역할 기반 접근 제어(RBAC)
Auth.js를 사용해 애플리케이션에 역할 기반 접근 제어(RBAC)를 추가하는 방법은 두 가지가 있습니다. 이 방법들은 여러분이 선택한 세션 전략에 따라 달라집니다. 각각의 예제를 살펴보겠습니다.
역할(role) 가져오기
사용자의 역할을 결정하기 위해 프로바이더 설정에 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()
콜백을 사용하여 역할(role)을 쿠키에 저장할 수 있습니다. 로그인 시, profile
콜백에서 user
객체의 role
속성을 노출시킵니다. 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를 사용하여 이를 수행하는 방법을 보여주지만, 모든 어댑터에서 동일한 개념이 적용됩니다.
먼저, User 모델에 role
컬럼을 추가합니다.
model User {
id String @id @default(cuid())
name String?
email String? @unique
emailVerified DateTime?
image String?
role String? // 새로운 컬럼
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를 사용할 때는 페이지를 렌더링하기 전에 사용자의 역할을 기반으로 리디렉션하는 미들웨어를 사용할 수도 있습니다.