【Next.js】Auth0で取得したユーザー情報を編集する方法

2020/12/06に公開

前回の記事でNext.jsでAuth0を導入する方法を紹介し、api/meのAPI内でhandleProfileを使いユーザー情報を取得する方法について解説しました。

しかし、このメソッドを使ってGoogleでログインすると名前やメールアドレスなどが含まれている状態で個人情報が含まれてしまいます。

不用意に個人情報をセッションに持つのはセキュリティー上、危険ですよね。なので、今回の記事では必要なユーザー情報だけをセッションに格納する方法について解説します。

必要なユーザー情報だけを取得する

セッション情報を格納しているのはapi/callbackのhandleCallbackです。callbackファイルはAuth0でログイン認証をした後に、リダイレクトされセッション情報を格納しています。そのため、セッションに格納するユーザー情報を加工するには、このファイルの編集が必要です。

具体的にはhandleCallbackの3つ目の引数であるオプションにonUserLoadedを設定することでセッションを作る前の制御が可能となります。

page/api/callback.js

import auth0 from '../../lib/auth0';

export default async function callback(req, res) {
  try {
    await auth0.handleCallback(req, res, {
      onUserLoaded: async (req, res, session, state) => {
        return {
          ...session,
          
          //引数のセッション情報のユーザー情報を上書き
          user: {
            sub: session.user.sub,  //Auth0で与えられたID
          }
        };
      }
    });
  } catch (error) {
    console.error(error);
    res.status(error.status || 500).end(error.message);
  }
}

上記のコードではAuth0で採番されるsubというパラメータの値のみセッションのユーザー情報にセットしています。

これによりhandleProfileで取得したユーザー情報はsubのみになります。

page/index.js

import React from 'react';

import Layout from '../components/layout';
import { useFetchUser } from '../lib/user';

export default function Home() {
  const { user, loading } = useFetchUser();

  return (
    <Layout user={user} loading={loading}>
      <h1>Next.js and Auth0 Example</h1>

      {/* ロード中 */}
      {loading && <p>Loading login info...</p>}

      {/* ログアウト状態 */}
      {!loading && !user && (
        <>
          <p>
            To test the login click in <i>Login</i>
          </p>
          <p>
            Once you have logged in you should be able to click in <i>Profile</i> and <i>Logout</i>
          </p>
        </>
      )}

      {/* ログイン状態 */}
      {user && (
        <>
          <h4>Rendered user info on the client</h4>
          <pre>{JSON.stringify(user, null, 2)}</pre>
        </>
      )}
    </Layout>
  );
}

ユーザー情報を追加する

また、アプリ内だけで使うユーザー情報を追加することができます。たとえば、アプリ内で設定したニックネームなどをセッションに持たせて各ページで表示することも可能です。

その場合、先ほど使ったsubをキーにしてユーザー情報を取得するのが得策でしょう。

たとえば、以下のソースではsubをキーにDBから取得したユーザーをセッションに格納しています。

import auth0 from '../../lib/auth0';
import User from "@model/userModel";

export default async function callback(req, res) {
  try {
    await auth0.handleCallback(req, res, {
      onUserLoaded: async (req, res, session, state) => {
        
        //サブからユーザー情報を取得
        const user_info = await User.findOne({ raw: true, where: { sub: session.user.sub} });

        return {
          ...session,
          
          //引数のセッション情報のユーザー情報を上書き
          user: {
            ...user_info
          }
        };
      }
    });
  } catch (error) {
    console.error(error);
    res.status(error.status || 500).end(error.message);
  }
}

まとめ

  • Auth0から受け取ったユーザー情報をセッションに格納するのはhandleCallbackメソッド
  • onUserLoadedの引数のセッションにAuth0から受け取ったユーザー情報が渡ってくる
  • Auth0から受け取ったユーザー情報のsubはAuth0が採番したID

Discussion