🐈

Auth0のSDKを使ってNestJSからユーザーを登録する方法

2022/10/12に公開約4,500字

はじめに

Auth0のSDKを利用してAuth0 Management APIでユーザーをAUth0のDBに登録する方法についてまとめます。

参考資料はこちら

https://dev.classmethod.jp/articles/manage-auth0-users-using-auth0-management-api-with-nodejs/

必要なモジュールをインストール

https://www.npmjs.com/package/auth0

https://www.npmjs.com/package/@types/auth0

Auth0のモジュールを定義する

環境変数についてはConfigurationを利用して読み込んでいます

Auth0ManagementClientをインスタンス化するためのdomainclientIdclientSecretについては冒頭の参考資料に細かく説明されているのでそちらを参照ください

環境変数については本番環境・検証環境ごとにCloud Runに設定した環境変数をもとにプロセスから読み込むことを想定しています

https://cloud.google.com/run/docs/configuring/environment-variables?hl=ja

モジュールクラス
app/src/common/auth0/auth0.module.ts
import { Module } from '@nestjs/common'
import { LoggerModule } from 'nestjs-pino'
import { ConfigModule } from '@nestjs/config'
import { Auth0Service } from './auth0.service'

@Module({
  providers: [Auth0Service],
  exports: [Auth0Service],
  imports: [LoggerModule, ConfigModule],
})
export class Auth0Module {}
サービスクラス
app/src/common/auth0/auth0.service.ts
import { Injectable, InternalServerErrorException } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import { ManagementClient } from 'auth0'
import { CreateAuth0UserInput } from '../../types/auth0/CreateAuth0UserInput'
import { CreateAuth0UserOutput } from '../../types/auth0/CreateAuth0UserOutput'

@Injectable()
export class Auth0Service {
  private readonly auth0Client: ManagementClient
  private readonly AUTH0_CONNECTION = 'Username-Password-Authentication'

  constructor(private configService: ConfigService) {
    this.auth0Client = new ManagementClient({
      domain: this.configService.get('auth0.domain'),
      clientId: this.configService.get('auth0.clientId'),
      clientSecret: this.configService.get('auth0.clientSecret'),
      scope: 'create:users read:users update:users',
    })
  }

  async createUserByAuth0({
    email,
    password,
  }: CreateAuth0UserInput): Promise<CreateAuth0UserOutput> {
    try {
      const { user_id } = await this.auth0Client.createUser({
        connection: this.AUTH0_CONNECTION,
        email: email,
        password: password,
      })

      return {
        user_id: user_id,
      }
    } catch (e: unknown) {
      if (e instanceof Error) {
        throw new InternalServerErrorException(e.message)
      }
      
      throw new InternalServerErrorException(e)
    }
  }
}

Resolverを定義する

今回はGraphQLを利用するためResolverを定義していますが、RestAPIで実装されている場合はこちらの手順は不要になります。
使用するモジュールで先ほど定義したAuth0を操作するモジュールを依存注入してご利用ください。

InputType
app/src/types/auth0/CreateAuth0UserInput.ts
import { Field, InputType } from '@nestjs/graphql'

@InputType()
export class CreateAuth0UserInput {
  @Field()
  email: string

  @Field()
  password: string
}
ObjectType
app/src/types/auth0/CreateAuth0UserOutput.ts
import { Field, ObjectType } from '@nestjs/graphql'

@ObjectType()
export class CreateAuth0UserOutput {
  @Field()
  user_id: string
}
リゾルバクラス
app/src/author/author.resolver.ts
import { Args, Int, Mutation, Query, Resolver } from '@nestjs/graphql'
import { AuthorService } from './author.service'
import { Author } from './author.model'
import { CreateAuth0UserInput } from '../types/auth0/CreateAuth0UserInput'
import { Auth0Service } from '../common/auth0/auth0.service'
import { CreateAuth0UserOutput } from '../types/auth0/CreateAuth0UserOutput'

@Resolver(() => Author)
export class AuthorsResolver {
  constructor(
    private readonly authorsService: AuthorService,
    private readonly auth0Service: Auth0Service,
  ) {}

  @Query(() => String)
  async author() {
    return 'hoge'
  }

  @Mutation((returns) => CreateAuth0UserOutput)
  async saveUserByAuth0(
    @Args('auth0Data') auth0InputData: CreateAuth0UserInput,
  ) {
    return this.auth0Service.createUserByAuth0(auth0InputData)
  }
}
モジュールクラス
app/src/author/author.module.ts
import { Module } from '@nestjs/common'
import { AuthorService } from './author.service'
import { AuthorsResolver } from './author.resolver'
import { Auth0Module } from '../common/auth0/auth0.module'

@Module({
  imports: [Auth0Module],
  providers: [AuthorsResolver, AuthorService],
})
export class AuthorModule {}

実行してみる

成功するとAuthoで発行されたIDが返却されます

mutation MyMutation {
  saveUserByAuth0(auth0Data: {email: "hoge8@example.com", password: "Password1234"}) {
    user_id
  }
}

Discussion

ログインするとコメントできます