什么是 ouath?

OAuth 介绍

OAuth 流程

1. 使用 drizzle adapter:

文档: https://authjs.dev/getting-started/adapters/drizzle

  1. 安装依赖:
pnpm add drizzle-orm @auth/drizzle-adapter
pnpm add drizzle-kit --save-dev
  1. shcema.ts 中定义相关表:
import { text, pgTable, timestamp, integer, primaryKey, boolean } from 'drizzle-orm/pg-core'
import type { AdapterAccount } from "next-auth/adapters"

export const users = pgTable("user", {
  id: text("id")
    .primaryKey()
    .$defaultFn(() => crypto.randomUUID()),
  name: text("name"),
  email: text("email").unique(),
  emailVerified: timestamp("emailVerified", { mode: "date" }),
  image: text("image"),
})
 
export const accounts = pgTable(
  "account",
  {
    userId: text("userId")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    type: text("type").$type<AdapterAccount>().notNull(),
    provider: text("provider").notNull(),
    providerAccountId: text("providerAccountId").notNull(),
    refresh_token: text("refresh_token"),
    access_token: text("access_token"),
    expires_at: integer("expires_at"),
    token_type: text("token_type"),
    scope: text("scope"),
    id_token: text("id_token"),
    session_state: text("session_state"),
  },
  (account) => ({
    compoundKey: primaryKey({
      columns: [account.provider, account.providerAccountId],
    }),
  })
)
 
export const sessions = pgTable("session", {
  sessionToken: text("sessionToken").primaryKey(),
  userId: text("userId")
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  expires: timestamp("expires", { mode: "date" }).notNull(),
})
 
export const verificationTokens = pgTable(
  "verificationToken",
  {
    identifier: text("identifier").notNull(),
    token: text("token").notNull(),
    expires: timestamp("expires", { mode: "date" }).notNull(),
  },
  (verificationToken) => ({
    compositePk: primaryKey({
      columns: [verificationToken.identifier, verificationToken.token],
    }),
  })
)
 
export const authenticators = pgTable(
  "authenticator",
  {
    credentialID: text("credentialID").notNull().unique(),
    userId: text("userId")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    providerAccountId: text("providerAccountId").notNull(),
    credentialPublicKey: text("credentialPublicKey").notNull(),
    counter: integer("counter").notNull(),
    credentialDeviceType: text("credentialDeviceType").notNull(),
    credentialBackedUp: boolean("credentialBackedUp").notNull(),
    transports: text("transports"),
  },
  (authenticator) => ({
    compositePK: primaryKey({
      columns: [authenticator.userId, authenticator.credentialID],
    }),
  })
)
  1. 执行 npx drizzle-kit push 创建表

2. 使用 Gitlab Provider:

文档: https://authjs.dev/getting-started/providers/gitlab

  1. .env 中定义环境变量
AUTH_GITLAB_ID=""
AUTH_GITLAB_SECRET=""

如何获取 id 和 secret?到 Gitlab 页面 profile/preferences/Applications 中进行注册,重定向地址:http://localhost:3000/api/auth/callback/gitlab,权限 read_user,获取到 Application IDsecret

  1. route.ts 中配置 Gitlab Provider:
import NextAuth from "next-auth"
import Gitlab from "next-auth/providers/gitlab"

export const authOptions = {
  providers: [
    Gitlab({
      clientId: process.env.AUTH_GITLAB_ID!,
      clientSecret: process.env.AUTH_GITLAB_SECRET!
    })
  ]
}
const handler = NextAuth(authOptions)

export {
  handler as GET,
  handler as POST
}
  1. 访问:http://localhost:3000/api/auth/signin ,重定向到 gitlab 官方的授权页,点击授权: