안녕하세요. 인터넷의 어둠의 동맹자가 자신만의 인증 및 역할 기반 솔루션을 검색하고 있지만 아무것도 찾을 수 없거나 찾았을 수도 있지만 그렇지 않은 경우도 있습니다. 더 이상 작업하지 않으면 기능 코드가 있는 올바른 위치에 있는 것입니다. 여러분이 더 쉽게 사용할 수 있도록 패키지 버전도 제공하겠습니다.
이제 먼저 필요한 모든 패키지를 설치해 보겠습니다
npm install next-auth@beta npm install drizzle-orm zod react-hook-form
이제 nextAuth에 대한 인증 공급자를 설정해 보겠습니다.
lib/auth/index.ts
이 파일에서는 기본적으로 OAuth가 우리에게 어떤 역할도 돌려주지 않기 때문에 credentails 공급자를 사용할 것입니다. 그러나 oAuth를 사용하여 역할을 할당하는 방법도 알아볼 것입니다
export const { handlers, signIn, signOut, auth } = NextAuth({ adapter: DrizzleAdapter(db), providers: [ Credentials({ name: "credentials", credentials: { email: { type: "email", label: "Email Address", placeholder: "Email Address", }, password: { type: "password", label: "Password", }, }, async authorize(credentials) { const { email, password } = await signInSchema.parseAsync(credentials); const user = await db .select() .from(users) .where(eq(users.email, email)) .execute() .then((res) => res[0]); if (!user || !user.password) return null; const isValidPassword = await bcryptjs.compare(password, user.password); if (!isValidPassword) return null; return { id: user.id, name: user.name, email: user.email, }; }, }), GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, profile(profile: GoogleProfile) { return { ...profile, role: "user" }; }, }) ], });
이 정보를 DB에 저장하고 검색하기 위해 Postgres와 Drizzle ORM을 사용하고 있다는 점을 언급하는 것이 좋을 것 같습니다.
저희는 드리즐 어댑터를 사용하고 있습니다.
를 사용하여 설치할 수 있습니다.
npm install drizzle-orm @auth/drizzle-adapter npm install drizzle-kit --save-dev
인증이 작동하려면 여기 링크에서 Drizzle Suit 스키마를 찾을 수 있습니다. 이제 API 경로에서 이 핸들러를 사용하여 작동하게 하면 됩니다.
import { handlers } from "@/lib/auth"; export const { GET, POST } = handlers;
이제 인증이 작동하지만 아직 역할이 없습니다. 먼저 drizzle 스키마를 수정한 다음 nextAuth 옵션을 수정하겠습니다.
이것은 문자열 값을 보유하는 사용자 테이블의 역할로서 간단한 필드일 수 있다는 것을 기억하십시오. 하지만 이렇게 만든 이유는 역할을 원하는 만큼 만들고 권한을 추가할 수 있기 때문입니다
export const roles = pgTable("roles", { id: text("id") .primaryKey() .$defaultFn(() => createId()), name: text("name").notNull(), description: text("description"), }); export const permissions = pgTable("permissions", { id: text("id") .primaryKey() .$defaultFn(() => createId()), name: text("name").notNull(), description: text("description"), }); export const rolePermissions = pgTable("role_permissions", { roleId: text("roleId").references(() => roles.id, { onDelete: "cascade" }), permissionId: text("permissionId").references(() => permissions.id, { onDelete: "cascade", }), }); export const userRoles = pgTable("user_roles", { userId: text("userId").references(() => users.id, { onDelete: "cascade" }), roleId: text("roleId").references(() => roles.id, { onDelete: "cascade" }), });
이제 사용자 세션에 역할과 권한이 포함되도록 NextAuthOption을 수정해야 합니다.
먼저 역할을 직접 가져오기 위한 콜백 함수를 정의합니다.
callbacks: { async jwt({ token, user }) { if (user && user.id) { const { role, permissions } = await getUserRoleAndPermissions(user.id); token.role = role; token.permissions = permissions; } return token; }, async session({ session, token }) { if (token && session.user) { session.user.id = token.id; session.user.role = token.role; session.user.permissions = token.permissions; } return session; }, },
getRolesandPermission 함수는 drizzle을 사용하여 db에서 역할과 권한을 쿼리하는 것처럼 들리는 대로 작동합니다. 기본적으로 이것만으로는 작동하지 않으며 유형도 일부 변경해야 합니다.
declare module "next-auth" { interface Session { user: { id: string; role: string; permissions: string[]; } & DefaultSession["user"]; } } declare module "next-auth/jwt" { interface JWT { id: string; role: string; permissions: string[]; } }
이제 세션에 액세스하여 역할과 권한을 얻을 수 있습니다. 이를 사용하면 페이지 수준에서 사용자를 차단하거나 미들웨어를 사용하여 전체 경로 그룹을 보호할 수 있습니다.
이 방법은 다중 테넌트에서 매우 유용할 수 있으며 사용자를 다른 곳에 저장하고 싶지 않을 수도 있습니다. 이는 완벽한 솔루션입니다. 읽어주셔서 감사합니다
위 내용은 Nextauth 및 next.js를 사용한 역할 기반 인증의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!