Breaking News

Default Placeholder Default Placeholder

Webアプリケーションを作ると限られた人にだけアクセスできるようにしたいという願望が出てくると思います。

そんな時に使うのがユーザ認証の仕組みですが、自分で組み立てると意外と面倒だったりします。

今回はAuth0というサービスを使って、Reactのプロジェクトにユーザ認証の仕組みを取り入れる方法を解説します。

やることリスト

  1. Reactプロジェクトを作成する
  2. React Routerを導入する
  3. Auth0でSingle Page ApplicationのApplicationを作成する
  4. トップページにログインボタンを設置する
  5. ログインを必須とする画面遷移の仕組みを作る

1. Reactプロジェクトを作成する

以下のコマンドを使ってReact TypeScriptのプロジェクトを作成します。

Viteを使います。

Viteについてはこちらの公式サイトを参照してください https://ja.vitejs.dev/

$ npm create vite@latest react_auth0  -- --template react-ts
Need to install the following packages:
  create-vite@5.2.3
Ok to proceed? (y) y

Scaffolding project in /Users/kaitakahiko/projects/django_react_auth0_test/frontend/django_react_auth0...

Done. Now run:

  cd react_auth0
  npm install
  npm run dev

npm installで必要なパッケージをインストールし、npm run devしてブラウザでトップページが開けたらOKです 👍

2. React Routerを導入する

以下のコマンドを打って必要なライブラリをインストールします。

$ npm install react-router-dom @types/react-router-dom

次に適当なページを1つ追加します。

src/sample.tsxを作成します。トップページに戻りやすいようにトップページに遷移するボタンも追加してあげます。

import { Link } from "react-router-dom"

const Sample: React.FunctionComponent = () => {
  
  return (
    <div className="App">
      <p>This is Sample Page</p>
      <Link to="/"><p>Back To Top Page</p></Link>
    </div>
  )
}

export default Sample

src/main.tsxにRouterの設定をします。

/sampleというパスがURLに渡された場合はSampleページを開きますよ、という感じにします。

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import { BrowserRouter, Route } from 'react-router-dom'
import Sample from './sample.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <BrowserRouter>
      <Routes>
        <Route path="/sample" element={<Sample />} />
        <Route path="/" element={<App />} />
      </Routes>
    </BrowserRouter>
  </React.StrictMode>,
)

src/App.tsxに、Sampleページに遷移するボタンを用意し、画面遷移できるか確認します。

適当な位置にSampleページへのボタンを追加してください。

<Link to="/sample"><p>Sample Page</p></Link>

トップページにボタンが出てきたかと思います。Sampleページに画面遷移できたらOKです 👍

3. Auth0でSingle Page ApplicationのApplicationを作成する

Auth0の公式ページからアカウントを作成してください。

アカウントを作成したら、Applicationを作ります。

今回はReactを使うのでSingle Page ApplicationでAuto0 Applicationを作ります。

Applicationを作ったら、Settingsタブを開いてください。

そこで必要な設定を行なっていきます。設定が必要な項目は以下です

  • Allowed Callback URLs
  • Allowed Logout URLs
  • Allowed Web Origins

上記3つにhttp://localhost:5173を設定し、画面右下にあるSaveボタンでSaveします。

React + Viteのプロジェクトだと、デフォルトポートは5173なのでhttp://localhost:5173を指定します。

これでAuth0側での設定は終了です。

4. トップページにログインボタンを設置する

src/App.tsxにログインボタンを設置します。

以下のコードをApp.tsxに追加します。

...
...
import { useAuth0 } from "@auth0/auth0-react";
...
...

function App() {
  ...
  ...
  const { loginWithRedirect } = useAuth0();

  return (
    <>
      ...
      ...
      <button onClick={() => loginWithRedirect()}>
        Log in
      </button>

  )

次にsrc/main.tsxを修正します。

Auth0のSettingsページに表示してあるDomainClient IDを使用します。

import React from 'react'
import ReactDOM from 'react-dom/client'
import { Auth0Provider } from '@auth0/auth0-react';
import App from './App.tsx'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import Sample from './sample.tsx'
import './index.css'

ReactDOM.createRoot(document.getElementById('root')!).render(
  <Auth0Provider
      domain="xxxxxxxxxxxx.auth0.com"
      clientId="yyyyyyyyyyyyyyyyyyyy"
      authorizationParams={{
        redirect_uri: window.location.origin
      }}
    >
    <React.StrictMode>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<App />} />
          <Route path="/sample" element={<Sample />} />
        </Routes>
      </BrowserRouter>
    </React.StrictMode>
  </Auth0Provider>,
)

ログインボタンを押下して、Auth0のログイン画面に遷移し、認証に成功したらOKです 👍

5. ログインを必須とする画面遷移の仕組みを作る

2. React Routerを導入するで作成したSample画面をログイン必須画面とします。

Routerに一工夫します。

src/login_required.tsxを新規で作成します。Auth0でまだ認証されていない状態だとトップページ(/)に遷移するようにします。

import { Navigate, Outlet } from "react-router-dom";
import { useAuth0 } from "@auth0/auth0-react";

const LoginRequired = () => {
  const user = useAuth0();
  if (!user.isAuthenticated) return <Navigate to="/" />;
  return <Outlet />;
};

export default LoginRequired;

このLoginRequiredをRouterに仕込んでいきます。

src/main.tsxを以下のように修正します。

import React from 'react'
import ReactDOM from 'react-dom/client'
import { AppState, Auth0Provider } from '@auth0/auth0-react';
import App from './App.tsx'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import Sample from './sample.tsx'
import './index.css'
import LoginRequired from './login_required.tsx';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <Auth0Provider
      domain="xxxxxxxxxxxx.auth0.com"
      clientId="yyyyyyyyyyyyyyyyyyyy"
      authorizationParams={{
        redirect_uri: window.location.origin
      }}
    >
    <React.StrictMode>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<App />} />
          <Route element={<LoginRequired />}>
            <Route path="/sample" element={<Sample />} />
          </Route>
        </Routes>
      </BrowserRouter>
    </React.StrictMode>
  </Auth0Provider>,
)

このようにすることで、Sampleページはログインしていないと遷移できない状態になります。

ログインしていないと、2. React Routerを導入するで設置したSampleページへのボタンを押下しても遷移しないかと思います。