こんにちは、あなたも独自の認証とロールベースのソリューションを探してインターネットの暗い味方を探し回ったものの、何も見つからなかった、またはおそらく見つけたかもしれませんが、それは単に見つかりませんでしたもう作業できない場合は、機能コードが正しい場所にあります。皆さんにとって簡単になるように、パッケージのバージョンも示します。
それでは、まず必要なパッケージをすべてインストールしましょう
npm install next-auth@beta npm install drizzle-orm zod react-hook-form
次に、nextAuth の認証プロバイダーをセットアップしましょう。
にファイルが作成されます。lib/auth/index.ts
デフォルトでは OAuth はロールを返さないため、このファイルでは資格情報プロバイダーを使用しますが、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
認証が機能するための霧雨に適したスキーマは、ここのリンクで見つけることができます。あとは、API ルートでこのハンドラーを使用して機能させるだけです。
import { handlers } from "@/lib/auth"; export const { GET, POST } = handlers;
認証は機能するようになりましたが、まだロールがありません。まず霧雨スキーマを変更し、次に nextAuth オプションを変更します。
これは、文字列値を保持する users テーブル内のロールとしての単純なフィールドである可能性があることに注意してください。しかし、私はこのようにして、必要なだけロールを作成し、それに権限を追加できるようにしました
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[]; } }
セッションにアクセスすることで、役割と権限を取得できるようになりました。これを使用すると、ページ レベルでユーザーをブロックしたり、ミドルウェアを使用してルート グループ全体を保護したりできます。
この方法はマルチテナント Sass で非常に役立ちます。ユーザーを他の場所に保存したくない場合、これは完璧なソリューションです。読んでいただきありがとうございます
以上がNextauth と next.js を使用したロールベースの認証の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。