Next.jsによるWebアプリケーションにAuth0による認証機能を追加する方法の簡単なメモです。
以前、ViteでAuth0を少し試しましたが、Next.jsではやり方が異なるみたいです。以下のその①に相当しますが、プロフィール画像までは出しません。今回はほぼ初めて使う不慣れなTypeScriptでやっています。
- Viteでauth0を使ってみる ~ その① ログイン機能 (2021-08-03)
- Viteでauth0を使ってみる ~ その② APIの呼び出し (2021-08-07)
- Viteでauth0を使ってみる ~ その③ react-router-dom の導入とルートの保護 (2021-08-11)
- Auth0でのロールベースアクセス制御(RBAC) (2021-11-20)
- Auth0によるページの保護をReact Router v5からv6に変更 (2021-11-23)
準備
- Auth0のアカウントを作成する
- Auth0のテナントを作成及び/又はそのテナントに切り替える
Auth0のアプリケーションを作成する
- Auth0のダッシュボードで、アプリケーションを作成する。
- Auth0のダッシュボードのApplicationsから[+ Create Application]をクリックする。
- アプリケーション名を入力する。例:”My Next.js Autheticated App”
- アプリケーションタイプとして、”Regular Web Applications”を選択し、[Create]ボタンをクリックする。
- アプリケーションを設定する。
- Settingsタブで以下の設定をしますが、最初から表示されている設定は、.envファイルで設定します。
- Allowed Callback URLsに、”http://localhost:3000/api/auth/callback”を設定する。
- Allowed Logout URLsに、”http://localhost:3000/”を設定する。
- 一番下までスクロールし、[Save Changes]ボタンをクリックする。
.envファイルを設定する
.env.sample に以下を追加する。
:
AUTH0_SECRET=
AUTH0_BASE_URL=
AUTH0_ISSUER_BASE_URL=
AUTH0_CLIENT_ID=
COOKIE_SECRET=
.ignoreで .env.sample 以外の .env*ファイルが無視されるよう指定されていることを確認します。
例えば、.env.local ファイルに次のように設定します。詳細はこちらを参照。
:
AUTH0_SECRET= // Auth0のApplicationsのsettingのClient ID
AUTH0_BASE_URL= // http://localhost:3000 等
AUTH0_ISSUER_BASE_URL= // Auth0のApplicationsのsettingのDomain 例:https://pitang1965.jp.auth0.com
AUTH0_CLIENT_ID= // Auth0のApplicationsのsettingのClient Secret
AUTH0_SECRET= // 32文字以上のランダムな値
上記の AUTH0_SECRETの値は、ターミナルで以下のコマンドで生成することができます。
$ node -e "console.log(crypto.randomBytes(32).toString('hex'))"
@auth0/nextjs-auth0をインストールする
$ yarn add @auth0/nextjs-auth0
Next.jsアプリケーションにAPIを追加する
- src\pages\apiフォルダにauthフォルダを作成し、[…auth0].jsファイルを作成する。
import { handleAuth } from '@auth0/nextjs-auth0';
export default handleAuth();
2. src\pages_app.tsx に以下の行を追加する。
:
import { UserProvider } from '@auth0/nextjs-auth0'; <--- この行
:
function MyApp({ Component, pageProps }: AppPropsWithLayout) {
:
const getLayout = Component.getLayout ?? ((page) => page);
return getLayout(
<UserProvider> <--- この行
<Component {...pageProps} />
</UserProvider> <--- この行
);
}
3. src\components\Navbar.tsx を次のように設定しました。
- [ログイン]ボタンを押すと、Auth0の認証のダイアログが表示されます。
- 認証されるとホームページに戻り、[ログイン]ボタンが消えて、[ログアウト]ボタンと、「こんにちは、○○○さん。」が表示されます。
- [ログアウト]ボタンをクリックすると、[ログアウト]ボタンが消えて、「ログアウト中です。お待ちください…」が一瞬表示され、やがて[ログイン]ボタンが表示されます。
import React, { useState, useEffect } from 'react';
import TopMenu from '../components/TopMenu';
import Link from 'next/link';
import { useUser } from '@auth0/nextjs-auth0';
export default function Navbar() {
const { user, error, isLoading } = useUser();
const [message, setMessage] = useState('');
// ログアウトボタンを押してログアウトするまでの間
const [isLoggingOut, setIsLoggingOut] = useState(false);
useEffect(() => {
if (error) {
setMessage(`エラー:${error}`);
setIsLoggingOut(false);
} else if (isLoading) {
setIsLoggingOut(true);
setMessage(`読み込み中...`);
} else if (user) {
setMessage(`こんにちは、${user.name}さん。`);
setIsLoggingOut(false);
} else {
setMessage(`未ログイン`);
setIsLoggingOut(false);
}
}, [user, error, isLoading]);
return (
<>
<nav className='flex justify-between items-center'>
<div className='basis-1/3'>
<TopMenu />
</div>
<div className='basis-1/3 text-center'>
<Link href='/' passHref>
<p className='text-2xl font-bold text-grey-800'>バス時刻表</p>
</Link>
</div>
<div className='basis-1/3 text-right'>
<Link href='/api/auth/logout'>
<a
onClick={() => {
setIsLoggingOut(true);
setMessage('ログアウト中です。お待ちください...');
}}
className={`rounded bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 ${
!user || isLoggingOut ? 'hidden' : ''
}`}
>
ログアウト
</a>
</Link>
<Link href='/api/auth/login'>
<a
className={`rounded bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 ${
user || isLoggingOut ? 'hidden' : ''
}`}
>
ログイン
</a>
</Link>
</div>
</nav>
{user && <p className='mx-2 self-center mt-2'>{message}</p>}
</>
);
}
これで、next devスクリプトを再起動して、http://localhost:3000/apu/auth/login にアクセスすると、次の画面が表示されるはずです。
Auth0のApplication URIを設定する
Auth0のダッシュボードで当該ApplicationのApplication URIsセクションで下記の設定に変更します(デプロイ先を追加)。
Allowed Callback URLs
http://localhost:3000/api/auth/callback,https://j-bus-time-table.vercel.app/api/auth/callback
Allowed Logout URLs
http://localhost:3000, https://j-bus-time-table.vercel.app
Vercelにデプロイする
GitHubのリポジトリを選択してデプロイします(詳細省略)が、以下の環境変数を設定します。
AUTH0_SECRET:******
AUTH0_BASE_URL:https://j-bus-time-table.vercel.app
AUTH0_ISSUER_BASE_URL:https://pitang1965.jp.auth0.com
AUTH0_CLIENT_ID: ******
AUTH0_CLIENT_SECRET: ******
- Post TagsNext.js