🔑

【Auth0 × React】パスキー認証をサクッと試したいんや・・!

2024/12/29に公開

TL;DR

  • React と Auth0 を使ってパスキー認証を実装するで
  • 入門向けのハンズオン記事やで
  • 以上やで

はじめに

こんにちは!株式会社Rivine のつかもとです!
気がつけば約1年半振りの執筆です🫠 ご無沙汰しております。
アドベントカレンダー初参加です(メリークリスマス🎅&良いお年を🎍)。

※冒頭に会社宣伝を少し・・!
弊社、Studioを使った Web デザイン事業(ホームページ制作等)も始めました!
▽ 何卒!!!よろしく!!!!どーぞ!!!!! ▽
https://www.rivine.jp/web_design


さて、本題です。今回も例のごとくハンズオンです。
React アプリへ Auth0 のパスキー認証を取り入れたいと思います。

パスキー認証について・・・

本記事では「パスキー認証とは?」の詳細については割愛しますが、
ざっくり簡単に言えば以下の通りです。

  • パスキーは、パスワードに代わるより安全でシンプルな認証方式
  • 生体認証(指紋認証や顔認証など)、PIN等 を使用してアプリやウェブサイトにログイン可能
  • 従来のパスワード方式の課題であったパスワードを管理する運用が不要

※リンク集

昨今の React と Auth0 に少し触れる・・・

React については、12月にバージョン19がリリースされ、Actions をはじめとする新機能が追加されましたね!(※本記事では特に言及しておりません)
https://react.dev/blog/2024/12/05/react-19

また、Auth0 に関してですが、今回試すパスキー機能が 今年の1月に GA となりました。
https://auth0.com/changelog#3CBET2mBWyqK0RS6poEJiC

9月には無料プランの拡大もあり、コレが正直個人的には「神アプデじゃね?」って思っております。
https://www.publickey1.jp/blog/24/auth025000.html

MAU が 25,000 人まで拡充、カスタムドメイン使える、パスワードレス認証、ソーシャル連携の制限数撤廃 などなど・・・太っ腹ぶりがスゴイです!

過去の利用経験から開発/ユーザー体験は良かったのですが、正直なところ無料プランの機能制限が中々ネックではありました。
今回の無料プラン拡大により、これまでは有料プランでしか使えなかった機能が開放されたことはかなり嬉しいです・・!!

・・・

さて、前置きが長くなってしまったので、早速以下より作業を進めていきましょう!

React アプリケーションの作成

今回は Vite を使って開発を進めていきます。
まずは以下コマンドにて Vite プロジェクトを作成します。

$ npm create vite@latest

プロジェクト名を入力。ここでは react-passkey-auth とします。

Vite/Reactプロジェクト作成

フレームワークを聞かれるので React を選択

Vite/Reactプロジェクト作成

言語を聞かれるので今回は TypeScript + SWC を選択

...
Scaffolding project in /Users/…/react-passkey-auth...

Done. Now run:

  cd react-passkey-auth
  npm install
  npm run dev

無事に React プロジェクトが作成されました!
上記のガイド通りにコマンドを実行します。

$ cd react-passkey-auth
$ npm install
...
$ npm run dev
> react-passkey-auth@0.0.0 dev
> vite


  VITE v6.0.5  ready in 392 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

http://localhost:5173/ にアクセスし、以下の画面が表示されれば OK です!

Vite/Reactアプリ

Auth0 の認証基盤を構築

続いては Auth0 側の作業です!
Auth0 のアカウントが未登録の方は https://auth0.com/jp/signup から登録してください。
既に登録済の方は https://manage.auth0.com/dashboard へアクセスしてください。

テナントの作成

まずは今回利用するテナントを作成します(※アカウント作成のタイミングで作成されるデフォルトテナントを利用しても問題ないです)。

ダッシュボード左上のテナント選択エリアを選択 Create Tenant をクリック
テナント作成

Tenant DomainRegionEnvironment Tag を設定し、 Create ボタンをクリック

テナント作成

テナント作成作業は以上となります。

アプリケーションの作成

続いて、認証用のアプリケーションを作成します。
ダッシュボードから Applications -> Applications を開き、+ Create Application ボタンをクリック
アプリケーション作成

名前入力後、Applicationの種類は Single Page Web Applications を選択し、
Create ボタンをクリック
アプリケーション作成

これでアプリケーションが作成されました!
作成したアプリケーションの Setting タブ -> Basic InformationDomainClient ID を確認しておきましょう(本項目は後続の作業にて、利用します)
アプリケーション作成

次に同ページ下部にある Application URIs より、各種URLの設定を行います。
Allowed Callback URLsAllowed Logout URLsAllowed Web Origins
http://localhost:5173 を入力後、Save Chenges をクリック。
URL設定

  • Allowed Callback URLs : 認証完了後にリダイレクトされるURL
  • Allowed Logout URLs : ユーザーがログアウトした後に表示するURL
  • Allowed Web Origins : 本アプリケーションが許可するオリジン一覧

ここまでの作業でアプリケーション側の設定は完了です!

パスキー機能の有効化

Authentication -> Database を選択し、Username-Password-Authentication をクリック。
続けて Authentication Methods タブを選択します。初期状態ではユーザー認証の方法がパスワードのみとなっているため、Passkey のトグルをクリックして有効化します。
パスキー有効化

パスキー機能を利用するために複数の条件を満たす必要があり、条件に満たない場合は下記のようなポップアップが表示されます。
今回は認証プロファイルに「Identifier First login flowが有効化されていない」ことにより、
判定が PENDING となっています。
パスキー有効化

Authentication -> Authentication Profile より、Identifier First プロファイルを選択。
選択後、Save ボタンをクリックし、変更を反映。
パスキー有効化

確認のポップアップが表示されるため、Proceed ボタンをクリックすれば変更反映完了です。
パスキー有効化

再度 Authentication -> Database -> Username-Password-Authentication -> Authentication Methods を選択。Passkey のトグルをクリック後、問題なく有効化されることを確認。本作業でパスキー認証が利用できる状態になります!
パスキー有効化

画面デザインをカスタマイズ(任意)

※本手順は任意のため、不要であればスキップしてください。

アプリの表示言語を日本語に変更

デフォルトだと英語になっているため、日本語に変更します。
Setting -> LanguagesDefault Languageより
Japanese (ja) を選択し、 Save ボタンをクリック。
言語設定

アプリロゴを変更

アプリのロゴを任意の画像へ変更します。Applications の作成したアプリケーションを選択。
Setting タブ -> Application Properties -> Application Logo の画像を任意の画像へ変更。
アプリロゴ修正

ヘッダーロゴとカラーテーマを変更

Branding -> Universal LoginQuick Start 内にて、
ヘッダーロゴとカラーテーマの変更を行います。
ヘッダーロゴカラーテーマ修正

各種画面の表示文言を変更

Branding -> Universal Login 下部のAdvanced Options をクリック。
Custom Text タブより、各種画面の表示文言を変更することができます。
各種画面の表示文言変更

※今回文言変更した画面、および内容は以下の通り

ログイン画面 (login-id)

ログイン画面 (login-id)

サインアップ画面 (signup-id)

サインアップ画面 (signup-id)

パスキー作成画面 (passkey-erollment)

パスキー作成画面 (passkey-erollment)

アプリ認証画面 (consent)

アプリ認証画面 (consent)

React アプリへ Auth0 を組み込む

ライブラリのインストール

Auth0 公式の React 用ライブラリ、@auth0/auth0-react が提供されているので、インストールしましょう。

$ npm install @auth0/auth0-react

Auth0Provider の読み込み

メインページにて、App を Auth0 の Provider でラップします。
domainclientId については、先程Auth0のアプリケーション設定で確認した DomainClient ID の値を記載してください。

/src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { Auth0Provider } from '@auth0/auth0-react';
import './index.css';
import App from './App';

const root = createRoot(document.getElementById('root'));

root.render(
  <StrictMode>
    <Auth0Provider
        domain=“${Auth0アプリケーションのDomain}"
        clientId="${Auth0アプリケーションのClient ID}”
        authorizationParams={{
          redirect_uri: window.location.origin
        }}
      >
        <App />
      </Auth0Provider>
  </StrictMode>,
);

認証用の各種コンポーネントを作成

認証に必要なコンポーネントを以下の通り作成します。

ログイン

/src/login.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";

const LoginButton = () => {
  const { isAuthenticated, loginWithRedirect } = useAuth0();

  return (
    !isAuthenticated && (
      <button onClick={() => loginWithRedirect()}>Log In</button>
    )
  );
};

export default LoginButton;

ログイン用のボタンを表示します。
ボタンクリック後、Auth0のログインページへリダイレクトします。

ログアウト

/src/logout.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";

const LogoutButton = () => {
  const { isAuthenticated, logout } = useAuth0();

  return (
    isAuthenticated && (
      <button onClick={() => logout({ logoutParams: { returnTo: window.location.origin } })}>
        Log Out
      </button>
    )
  );
};

export default LogoutButton;

ログアウト用のボタンを表示します。ボタンクリック後、ログアウト処理を行います。

プロフィール情報

/src/profile.tsx
import React from "react";
import { useAuth0 } from "@auth0/auth0-react";

const Profile = () => {
  const { user, isAuthenticated, isLoading } = useAuth0();

  if (isLoading) {
    return <div>Loading ...</div>;
  }
  return (
    isAuthenticated && (
      <div>
        <img src={user?.picture} alt={user?.name} />
        <h2>{user?.name}</h2>
        <p>{user?.sub}</p>
        <p>{user?.updated_at}</p>
      </div>
    )
  );
};

export default Profile;

ログイン済ユーザーの各種情報を表示します。

App ページにて、コンポーネントを追加

上記にて作成した LoginButtonLogoutButtonProfile コンポーネントを読み込みます。

/src/App.tsx
import reactLogo from './assets/react.svg';
import viteLogo from '/vite.svg';
import './App.css';
import LoginButton from './login';
import LogoutButton from './logout';
import Profile from './profile';

function App() {
  return (
    <>
      <div>
        <a href="https://vite.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </div>
      <h1>Vite + React</h1>
      <LoginButton></LoginButton>
      <LogoutButton></LogoutButton>
      <Profile></Profile>
    </>
  )
}

export default App

いざ!動作確認

ここまでで一通りの設定 (Auth0) と実装 (React) が完了したため
パスキー認証が正しく行えるかどうか、動作確認を進めていきます!

まずは以下コマンドにて、ローカルサーバーを起動します。

$ npm run dev

http://localhost:5173/ にアクセスし、以下の画面が表示されることを確認しましょう。

動作確認

画面に表示されている Log In ボタンをクリックしてください。
Auth0 側のログインページへ遷移します!

アカウント登録&パスキー作成

アカウントの新規登録とパスキーの作成を行っていきます。

表示されている Auth0 のログインページの アカウント登録 リンクをクリック。
アカウント登録&パスキー作成

アカウント登録ページへ遷移するので、登録メールアドレスを入力後 次へ ボタンをクリック。
アカウント登録&パスキー作成

画面の表示内容を確認し、パスキーを作成 ボタンをクリック。
アカウント登録&パスキー作成

今回は Google Chrome のブラウザにて動作検証をしているため
Google パスワード マネージャーにてパスキーの作成/管理を行っていきます。
アカウント登録&パスキー作成

パスキーの作成ができました!🙌
アカウント登録&パスキー作成

アプリケーションの認証許可を行う必要があるため、許可 ボタンをクリック。
アカウント登録&パスキー作成

パスキーを使ってログイン

それでは、上記で作成したパスキーをて利用しログインをしてみましょう!(やっとです・・)
Auth0 のログインページにて パスキーを使用して続行する ボタンをクリック。
パスキーログイン

保存済のパスキーを使用するかどうか確認されるため、そのまま認証作業を進めていきます。
パスキーログイン

キターー!!パスキーを使って無事にログインすることができました!🙌
パスキーログイン

ログアウト

最後に、上記 Log Out ボタンより、ログアウト処理が行われるかどうか確認しておきましょう。
ボタンクリック後、再度以下の表示になることを確認できれば、本動作確認作業は完了です!
ログアウト

おわりに

今回は Auth0 が提供するパスキー機能を使い、React アプリ上にてパスキー認証を試してみました。従来のパスワード認証よりも安全に利用できる仕組みは嬉しい限りですね!
最後まで読んでいただきありがとうございました!


株式会社Rivine では「テクノロジーで、もっと生きやすい世の中へ」をモットーに掲げ一緒に働く仲間を募集しております。関西にお住まいのエンジニアの皆様、是非ともご応募をお待ちしております!
https://www.rivine.jp/recruit/

株式会社Rivine

Discussion