🐡

Next.js(Auth.js)でGoogle Oauth2認証を実装する

2023/08/27に公開

実装します。

以下の記事を参考にさせていただきました
https://zenn.dev/ohtasoji/articles/5f893b45672095

公式のサンプル
スタートのページにあるのはJavaScriptのサンプルなのでTypeScriptのサンプルをもとに動かす
https://github.com/nextauthjs/next-auth-example

プロジェクトのクローン

$ git clone https://github.com/nextauthjs/next-auth-example

GoogleAPIConsoleで認証の設定をする

認証に使うドメインと認証成功時にリダイレクトを受け取るURLを指定する。Auth.jsのリダイレクト先は /api/auth/callback/google となるらしいので、そのように設定する。

Dockerで動かすために2つのファイルをコピーする

クローンしたディレクトリに2ファイル追加する

dockerfile
FROM node:18.17-alpine

WORKDIR /app/

COPY ./package.json ./
RUN npm install

GoogleのOauth2の認証に使うクライアントIDとシークレットの文字列を定義する。また認証時に利用するURL(NEXTAUTH_URL)も指定する必要があるとのことなので定義する

docker-compose.yml
services:
  app:
    build:
      context: .
    ports:
      - "5556:5556"
    volumes:
      - .:/app
      - node_modules:/app/node_modules
    command: sh -c "npm run dev -- -p 5556"
    environment:
      - GOOGLE_ID=<クライアントID>
      - GOOGLE_SECRET=<シークレット>
      - NEXTAUTH_URL=http://localhost:5556
volumes:
  node_modules:

認証を試す

Dockerをupしてトップページが確認できた

画面上の「Sign in」を押下してGoogleでログインした

http://localhost:5556/api/auth/session にアクセスするとユーザー情報をJSONで取得できます
https://github.com/nextauthjs/next-auth-example/blob/main/pages/api/examples/session.ts

認証ライブラリの機能がほぼ全て揃った状態で利用可能です。ドキュメントを流し読みしていましたがサインインのCallbackで色々処理を実装できそうです。
https://next-auth.js.org/configuration/callbacks

[...nextauth].ts
import NextAuth, { NextAuthOptions } from "next-auth"
import GoogleProvider from "next-auth/providers/google"

export const authOptions: NextAuthOptions = {
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
  }),
  ],
  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      console.log("signIn", user, account, profile, email, credentials)
      const isAllowedToSignIn = true
      if (isAllowedToSignIn) {
        return true
      } else {
        return false
      }
    },
    async jwt({ token }) {
      token.userRole = "admin"
      return token
    },
  },
}
export default NextAuth(authOptions)

callbacksの中で signIn しているところでコンソールに変数の内容を出してみたところ、以下のように出力されたので、ここで存在確認をして、メールアドレスが登録済みであれば既存ユーザーとして扱い、存在しなければ新規ユーザーとして扱えたらと思います。

next-auth-example-app-1  | signIn {
next-auth-example-app-1  |   id: '<ID>',
next-auth-example-app-1  |   name: '草苅快',
next-auth-example-app-1  |   email: 'kai.kusakari@gmail.com',
next-auth-example-app-1  |   image: 'https://lh3.googleusercontent.com/a/AAcHTtdVXbXt-v-PZr7Pbj4AsyUMkZJk6XzqsaU5ajgIbBvX1w=s96-c'
next-auth-example-app-1  | }

Discussion