LoginSignup
7
1

More than 1 year has passed since last update.

【Next.js】Auth0を認証に使用する場合のメモ

Posted at

Next.jsで、認証のプラットフォームにAuth0を用いる際のメモ。概ねここに書いてあるのだが…自分用の備忘録として。なお、Auth0はFreeでもいいのでなんらか既にアカウントを持っていることを前提とする。

Auth0 - Create Application

「Regular Web Applications」を選ぶ。Next.jsだと「Single Web Applications」とか選びたくなるが、それではない。

01.png

Auth0 - Settingsタブ

  • 「Application URLs」のコーナーにおいて、「Allowed Callback URLs」にhttp://localhost:3000/api/auth/callbackをいれる。これはローカルでNext.js立ち上げたときのコールバックURL。ポートはデフォの3000にしてるけど環境によって変えてる場合は要変更。他環境の分いれるときは、カンマ(,)区切りでこの後URLを続けて書いていく。間にスペースとかは特に不要。基本的に、各URLの末尾に/api/auth/callback入れとけばよい。
  • 「Allowed Logout URLs」にhttp://localhost:3000/をいれる。これもローカルでNext.js立ち上げたときのコールバックURL。ポート変えてる場合は同様にポート要変更。上と同じようにカンマ(,)区切りで複数のURLを指定できる。各URLのルートにあたるパス/を指定しておけばとりあえずOKらしい

02.png

環境変数の準備

  • ローカルだと.env.local をつくって以下のような内容を書き込めばよい。どういう値にすればいいとかそういう細かい話はGitHubで説明されている。ただ、Auth0でアプリケーション作ったあと、「Quick Start」タブの「Configure the SDK」っていう場所にほぼそのままコピペ可能な内容で(つくったアプリケーションのClient IDやClient Secret等がそのまま .env の形式で使用できる形で)載ってるので、それこのままコピペしたほうが良い。(画像参照)
  • GitHubにも書いてあるが、唯一 AUTH0_SECRET だけは自分で用意しなければならない。コマンドは指示されていて、openssl rand -hex 32を実行して出力された値をコピって貼り付ければよいだけである。

03.png

/pages/api/auth/[...auth0].js

  • 各プロジェクトに/pages/api/auth/[...auth0].js というファイルを用意する。内容のサンプルはAuth0がGitHubに載せている。超スッキリしてるけどこれだけで認証部分は動く。一応。
  • ただ逆に言うとこれは「最低限の動作」をするようにしか書かれていないので、これだけだとあんまりイケてなかったりする。例えばログインした直後に同じページにまた戻ってくるので、「ログイン後にポータル(的な)画面に遷移させたいなあ」とか、そういうもうちょっと複雑な動きさせたいなーとか思ったらこれに少し手を加える必要がある。これはhandleLoginreturnToにパスを指定することで実現できる。(参考)こんなかんじ↓
    /pages/api/auth/[...auth0].js
    import { handleAuth , handleLogin, handleLogout } from '@auth0/nextjs-auth0';
    
    export default handleAuth({
        async login(req, res) {
          await handleLogin(req, res, {
            returnTo: "/portal",
            authorizationParams: {
              scope: 'openid profile email read:products', 
            }
          });
        },
        async logout(req,res) {
          await handleLogout(req,res , {
            returnTo: '/',
          });
        },
    });
    

ログイン判定

@auth0/nextjs-auth0/clientからuseUserをimportして、userオブジェクトの有無で切り分けできる。各画面でやるっていうよりは、共通のコンポーネント(Layoutとか)に仕込んでおいて、どの画面でも未ログインだったりセッション切れてたらログイン促すような感じにしておいた方がいいのではないかと思う。(私は個人的にそうやってます)なお、ログインは/api/auth/loginにリンクさせれば、(環境変数や/pages/api/auth/[...auth0].jsがちゃんと整備されている前提であれば)それでそのままAuth0のログイン画面に飛んでいく。ので、userオブジェクトがNullの場合は、Linkでも用意してここに遷移させればいい。こんなかんじ↓

/components/layaout.tsx
import { useUser } from '@auth0/nextjs-auth0/client';
import { ReactNode } from "react";

type Props = {
  children?: ReactNode;
};

const Layout = ({ children }: Props) => {
  const { user, error, isLoading } = useUser();
  return (
    <>
        {user ? <div>
                    <p>こんにちは {user.email}</p>
                    {children}
                </div>
             : <div>
                    <Link href="/api/auth/login">
                        ログインする
                    </Link>
                </div>
        }
    </>
  );
};


export default Layout;

ログインが必要なAPI

ログイン後の画面操作でAPIを呼び出す際に、「ログインしていること」を前提とするAPIを作りたいときは、@auth0/nextjs-auth0からwithApiAuthRequiredというfunctionをimportして、これでfunctionをラップする。(参考)こんなかんじ↓

/pages/api/auth-api-test.ts
import type { NextApiRequest , NextApiResponse } from 'next';
import { withApiAuthRequired, } from '@auth0/nextjs-auth0';

const authApiTest = withApiAuthRequired(function api (req: NextApiRequest, res: NextApiResponse){
    const test = String(req.query.test);
    res.status(200).json({text: test});
});

export default authApiTest;

このAPIをログインしないで叩くと以下のようなレスポンスが返ってくる。HTTP statusは401 Unauthorized

{"error":"not_authenticated","description":"The user does not have an active session or is not authenticated"}

環境

    "@auth0/nextjs-auth0": "^2.3.1",
    "next": "13.2.4",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "typescript": "5.0.2"
7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1