首頁 >web前端 >js教程 >使用 Nextauth 和 next.js 基於角色的身份驗證

使用 Nextauth 和 next.js 基於角色的身份驗證

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB原創
2024-07-22 10:15:31787瀏覽

Roles based authentication using Nextauth and next.js

您好,所以如果您也想在互聯網的黑暗盟友中搜索您自己的身份驗證和基於角色的解決方案,但您找不到任何解決方案,或者也許您找到了,但事實並非如此如果你不再工作了,那麼你就在正確的地方使用了功能代碼,我還將提供軟體包版本,這樣對你們來說會更容易。

現在讓我們先安裝您需要的所有軟體包

  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" };
      },
    })
  ],
});

也許是時候提一下我正在使用 postgres 和 drizzle ORM 來保存和從資料庫檢索此資訊。

我們正在使用 drizzle 轉接器,您可以使用它來安裝它

npm install drizzle-orm @auth/drizzle-adapter
npm install drizzle-kit --save-dev

您可以在此處連結中找到適合 drizzle 的架構,以便進行身份驗證。現在我們只需在 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[];
  }
}

現在透過存取會話我們可以獲得角色和權限。透過使用它,您可以在頁面層級封鎖用戶,或使用中間件來保護您可以保護的整個路由群組。

此方法在多租戶 sass 中非常有用,可能您不想將用戶保存在其他地方,這是一個完美的解決方案。感謝您閱讀本文

以上是使用 Nextauth 和 next.js 基於角色的身份驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn