コンテンツへスキップ
NextAuth.js v4からの移行?こちらを ご覧ください。.

TypeORM アダプター

リソース

設定

インストール

npm install @auth/typeorm-adapter typeorm

環境変数

AUTH_TYPEORM_CONNECTION=postgres://postgres:adminadmin@0.0.0.0:5432/db

設定

./auth.ts
import NextAuth from "next-auth"
import { TypeORMAdapter } from "@auth/typeorm-adapter"
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: TypeORMAdapter(process.env.AUTH_TYPEORM_CONNECTION),
})

TypeORMAdapterは、接続文字列、またはConnectionOptionsオブジェクトを最初の引数として受け取ります。

高度な使用方法

カスタムモデル

TypeORMアダプターは、Entityクラスを使用してデータの構造を定義します。

デフォルトのエンティティをオーバーライドし、カスタムエンティティファイルを使用して追加のフィールドを追加できます。

  1. 変更されたエンティティを含むファイルを作成します。
lib/entities.ts
import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  ManyToOne,
  OneToMany,
  ValueTransformer,
} from "typeorm"
 
const transformer: Record<"date" | "bigint", ValueTransformer> = {
  date: {
    from: (date: string | null) => date && new Date(parseInt(date, 10)),
    to: (date?: Date) => date?.valueOf().toString(),
  },
  bigint: {
    from: (bigInt: string | null) => bigInt && parseInt(bigInt, 10),
    to: (bigInt?: number) => bigInt?.toString(),
  },
}
 
@Entity({ name: "users" })
export class UserEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column({ type: "varchar", nullable: true })
  name!: string | null
 
  @Column({ type: "varchar", nullable: true, unique: true })
  email!: string | null
 
  @Column({ type: "varchar", nullable: true, transformer: transformer.date })
  emailVerified!: string | null
 
  @Column({ type: "varchar", nullable: true })
  image!: string | null
 
+ @Column({ type: "varchar", nullable: true })
+ role!: string | null
 
  @OneToMany(() => SessionEntity, (session) => session.userId)
  sessions!: SessionEntity[]
 
  @OneToMany(() => AccountEntity, (account) => account.userId)
  accounts!: AccountEntity[]
}
 
@Entity({ name: "accounts" })
export class AccountEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column({ type: "uuid" })
  userId!: string
 
  @Column()
  type!: string
 
  @Column()
  provider!: string
 
  @Column()
  providerAccountId!: string
 
  @Column({ type: "varchar", nullable: true })
  refresh_token!: string | null
 
  @Column({ type: "varchar", nullable: true })
  access_token!: string | null
 
  @Column({
    nullable: true,
    type: "bigint",
    transformer: transformer.bigint,
  })
  expires_at!: number | null
 
  @Column({ type: "varchar", nullable: true })
  token_type!: string | null
 
  @Column({ type: "varchar", nullable: true })
  scope!: string | null
 
  @Column({ type: "varchar", nullable: true })
  id_token!: string | null
 
  @Column({ type: "varchar", nullable: true })
  session_state!: string | null
 
  @Column({ type: "varchar", nullable: true })
  oauth_token_secret!: string | null
 
  @Column({ type: "varchar", nullable: true })
  oauth_token!: string | null
 
  @ManyToOne(() => UserEntity, (user) => user.accounts, {
    createForeignKeyConstraints: true,
  })
  user!: UserEntity
}
 
@Entity({ name: "sessions" })
export class SessionEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column({ unique: true })
  sessionToken!: string
 
  @Column({ type: "uuid" })
  userId!: string
 
  @Column({ transformer: transformer.date })
  expires!: string
 
  @ManyToOne(() => UserEntity, (user) => user.sessions)
  user!: UserEntity
}
 
@Entity({ name: "verification_tokens" })
export class VerificationTokenEntity {
  @PrimaryGeneratedColumn("uuid")
  id!: string
 
  @Column()
  token!: string
 
  @Column()
  identifier!: string
 
  @Column({ transformer: transformer.date })
  expires!: string
}
  1. それらをTypeORMAdapterに渡します。
./auth.ts
import NextAuth from "next-auth"
import { TypeORMAdapter } from "@auth/typeorm-adapter"
import * as entities from "lib/entities"
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: TypeORMAdapter("yourconnectionstring", { entities }),
})

TypeORMのsynchronize: trueオプションは、エンティティと完全に一致するSQLを生成します。これにより、エンティティモデルで見つかった変更が自動的に適用されます。これは開発において便利なオプションです。

⚠️

synchronize: trueは、構成されたスキーマが期待されるスキーマと一致しない場合、データ損失が発生する可能性があるため、本番データベースに対して有効にするべきではありません!本番データベースの同期/マイグレーションはビルド時に実行することをお勧めします。

命名規則

snake_caseとcamelCaseの列名が混在している場合、または基盤となるデータベースシステムで問題が発生する場合は、TypeORMのネーミング戦略機能を使用してターゲットフィールド名を変更することをお勧めします。typeorm-naming-strategiesというパッケージがあり、Auth.jsが期待するフィールドを実際のデータベースのsnake_caseに変換するsnake_case戦略が含まれています。

たとえば、NextAuth設定の接続オブジェクトにネーミング規則オプションを追加できます。

./auth.ts
import NextAuth from "next-auth"
import { TypeORMAdapter } from "@auth/typeorm-adapter"
import { SnakeNamingStrategy } from "typeorm-naming-strategies"
import { ConnectionOptions } from "typeorm"
 
const connection: ConnectionOptions = {
  type: "mysql",
  host: "localhost",
  port: 3306,
  username: "test",
  password: "test",
  database: "test",
  namingStrategy: new SnakeNamingStrategy(),
}
 
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: TypeORMAdapter(connection),
})
Auth.js © Balázs Orbán and Team -2024