Neightbor.
ブログ

Blog

【Next.js】NextAuthを使った環境でのメールアドレス変更機能を実装する

【Next.js】NextAuthを使った環境でのメールアドレス変更機能を実装する-サムネイル

今回はNext.jsアプリケーションでNextAuthを活用し、メールアドレスとパスワードでの認証機能を実装した環境で、マイページ等からメールアドレスを変更する方法をまとめて行きます。

NextAuthの導入設定等の方法は以前まとめた以下の記事を参考にしてもらえればと思います。

【Next.js】NextAuthを使ってメールアドレスとパスワードでログインできる認証機能を実装する

NextAuthでは、ログイン後に認証情報をデータベースに保存する方式とJWTとしてクライアント側に保持する方式がありますが、今回はJWTの方式の設定で話を進めていきます。

メールアドレス変更の課題

本題に入る前にメールアドレスを変更する際の課題点を定義しておきます。

NextAuthでログインした場合、認証成功後に取得した情報はクライアント側のCookieへと保存されます。
アプリケーションはそのCookieに保存された値を利用することで、ログインしているユーザのメールアドレスや名前などの情報を取得することができます。

この値はログイン時に取得した情報を保持するため、ログイン中にマイページ等の機能からメールアドレスを修正した場合、次にログインするまでこのCookieに変更後のメールアドレスが保存されることはありません。

そのため、このCookie内の情報をもとに画面上にメールアドレスを表示するような仕組みがあると、変更前の古いメールアドレスが表示されたままになってしまいます。

今回はこの課題を解決するため、メールアドレス変更と同時にCookie内のNextAuth認証情報にあるメールアドレスも変更行えるようにしてきます。

NextAuthの設定変更

import { Session } from 'next-auth'
import { JWT } from 'next-auth/jwt'

import CredentialsProvider from 'next-auth/providers/credentials'
import { randomUUID, randomBytes } from 'crypto'

export const authOptions = {
  /* providers */
  providers: [...],

  /* callbacks */
  callbacks: {
    jwt: async ({ token, trigger, session, user }: { token: JWT, trigger?: string, session: { newEmail?: string, password?: string }, user: Session['user'] }) => {
      // JWTを更新
      if (trigger === 'update') {
        return {
          ...token,
          email: session.newEmail
        }
      }

      return token
    },
    session: async ({ session, trigger, newSession, token }: { session: Session, trigger: string, newSession: Session['user'], token: JWT }) => {
      session.user.id = String(token.sub)

      // sessionを更新
      if (trigger === 'update') {
        session.user.email = newSession.email
      }

      return session
    }
  }
}

NextAuth設定callbacks内のjwtとsessionにそれぞれif(trigger === ‘update’)の処理を追加してあげます。

これにより、アプリケーション側でNextAuthのupdateメソッドが実行された際に、JWTのemailとsessionのemailを新しいメールアドレスで更新できるようにしておきます。

メールアドレス変更処理を書く

'use client'
import { useSession } from 'next-auth/react'

export default function EditEmail() {
  const { data: session, update } = useSession()
  
  const updateEmail = async (newEmail) => {
    try {
      // DBへのメールアドレス変更適用処理
      const result = await ~~~
  
      // NextAuthの認証情報更新
      update({
        newEmail: newEmail
      })
    } catch (error) {
      // エラー時の処理 
    }
  }

  return (
    // メールアドレス設定変更画面のView
  )
}

余計な箇所は省略していますが、NextAuthのJWTやsessionは上記のように更新できます。

updateに更新情報を持たせることで、先ほどNextAuthの設定変更で用意した更新のif(trigger === ‘update’)内の処理が実行され、JWTおよびsessionのemailが変更後のメールアドレスとなります。

これで再ログインする必要なく、最新状態にすることができます。

今回はメールアドレスの変更にのみフォーカスしていますが、名前の変更やその他の情報変更をする際も今回の設定方法を参考にしてもらうことができます。

目的のサービスを探す

Service

株式会社Neightbor.は、お客様が抱える様々なお悩みに寄り添い、共に解決できる道を模索します。
お求めのサービスからお気軽にご相談ください。