今回はAuth0でログイン認証する簡単な認証利用アプリ(WEBアプリ)を作成します。
~目次~
- ReactでOpenID Connectを実装する~その1 準備
- ReactでOpenID Connectを実装する~その2 Auth0サービスを使ってみる (Auth0設定編)
- ReactでOpenID Connectを実装する~その3 Auth0サービスを使ってみる (アプリ開発編) ☆この記事☆
- ReactでOpenID Connectを実装する~その4 react-oidcを使ってみる
ReactでOpenID Connectを実装する~その5 自前認証プロバイダを立ち上げてみる(処理フロー編) - ReactでOpenID Connectを実装する~その6 自前認証プロバイダを立ち上げてみる(認証プロバイダ編)
- ReactでOpenID Connectを実装する~その7 自前認証プロバイダを立ち上げてみる(認証利用アプリ編)
- ReactでOpenID Connectを実装する~その8 あとがき
簡単な認証利用アプリをコーディングしてみる
事前準備
ReactでOpenID Connectを実装する~その1で作成したサンプルプログラム(authsample0)をコピーして、ログイン認証を実装したサンプルプログラム(authsample1)を作ります。
(authsample0があるディレクトリに移動しておきます)
$ cp -r authsample0 authsample1
$ cd authsample1
Auth0が提供するライブラリ(@auth0/auth0-react)をインストールします。
$ npm install @auth0/auth0-react
トップ画面(index.js)
import React from 'react';
import ReactDOM from 'react-dom';
import { Auth0Provider } from '@auth0/auth0-react';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
// Auth0管理画面で取得した値を<Auth0Provider>の各値に設定する。
// domain, clientId, audience
ReactDOM.render(
<React.StrictMode>
<Auth0Provider
domain="dev-******.us.auth0.com"
clientId="mhrvyvJBTZ701BzU****************"
audience="https://dev-******.us.auth0.com/api/v2/"
redirectUri={window.location.origin}
>
<App />
</Auth0Provider>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
import { Auth0Provider } from '@auth0/auth0-react';
先ほどインストールしたAuth0が提供するライブラリ(@auth0/auth0-react)を読み込みます。
<Auth0Provider>~</Auth0Provider>
Auth0が提供するタグです。メイン部である<App />を囲むように記述しているので、<App />全体がログイン認証の制御範囲になります。
domain
Auth0の設定情報で記載されていたDomainを設定します。
clientId
Auth0の設定情報で記載されていたClient IDを設定します。
audience
Auth0のAPI設定で記載されていたIdentifierのURL文字列を設定します。
domain, clientId, audienceの値がAuth0管理画面で表示されている値が異なっているとうまく接続できないため慎重に入力しましょう。
メイン部 (main.js)
メイン部分にあたるmain.jsを次のように修正します。
import React from 'react';
import { useAuth0 } from '@auth0/auth0-react';
import AppHeader from './AppHeader';
import AppContents from './AppContents';
import './App.css';
function App() {
// Auth0が提供する認証用定義
const {
isLoading,
isAuthenticated,
error,
user, // ユーザー情報(TUser型)
loginWithRedirect, // Auth0にログイン画面を表示するよう要求
logout, // Auth0に現在のユーザをログアウトするよう要求
} = useAuth0();
// Auth0への接続処理中の場合
if (isLoading) {
return (
<div className="App">
<div className="AppHeader">
<AppHeader />
</div>
<div className="AppContents">
Auth0を利用した認証処理中...
</div>
</div>
);
}
// Auth0で認証エラー発生した場合
if (error) {
return (
<div className="App">
<div className="AppHeader">
<AppHeader />
</div>
<div className="AppContents">
認証エラー発生 ({error.message})
</div>
</div>
);
}
// Auth0で正常に認証できた場合 (→ログイン後の画面を表示する)
if (isAuthenticated) {
return (
<div className="App">
<div className="AppHeader">
<AppHeader logoutFunc={logout}/>
</div>
<div className="AppContents">
<AppContents user={user}/>
</div>
</div>
);
// 認証前の画面表示 (→ログインボタンを表示する)
} else {
return (
<div className="App">
<div className="AppHeader">
<AppHeader logoutFunc="" />
</div>
<div className="AppContents">
<button onClick={loginWithRedirect}>ログイン</button>
</div>
</div>
);
}
}
export default App;
const { ... } = useAuth0();
Auth0が提供する認証用の定義情報です。とりあえずこのままコピペしましょう。
if (isLoading) ...
isLoadingがtrueの場合、Auth0で認証処理をしている最中の状態になります。画面には「認証処理中...」などと表示して、ユーザに処理途中である旨を知らせます。
if (error) ...
errorがtrueの場合、Auth0で認証失敗しています。エラー画面を表示します。
if (isAuthenticated) ...
isAuthenticatedがtrueの場合、Auth0で正常にログイン認証ができた状態です。ログイン後に表示するメイン画面を出力します。
今回はヘッダ部<AppHeader>にlogoutメソッドを渡し、コンテンツ部<AppContents>にuser情報一式を渡して、各タグに表示処理を移譲しています。
if (isAuthenticated) ... else ...
isAuthenticatedがfalseの場合、まだログイン認証ができていない状態ですので、画面上にログインボタンを表示します。
ログインボタン押下時(onClick)はloginWithRedirectメソッドを呼び出して、Auth0ログイン画面を表示するよう要求します。
ヘッダ部 (AppHeader.js)
ヘッダ部にあたるAppHeader.jsを次のように修正します。
import React from 'react';
import './AppHeader.css';
function AppHeader(props) {
// ログアウトボタン押下時
const handleLogout = (event) => {
console.log(event.target.value);
props.logoutFunc({ returnTo: window.location.origin });
}
// ログアウト関数が指定されている場合 (→ログアウトボタンを表示)
if (props.logoutFunc){
return (
<div className="AppHeader">
<span></span>
<span>OpenID Connect Sample 1</span>
<span className='right'>
<button onClick={handleLogout}>Logout</button>
</span>
</div>
);
// ログアウト関数が指定されていない場合 (→ログアウトボタンは非表示)
} else {
return (
<div className="AppHeader">
<span></span>
<span>OpenID Connect Sample 1</span>
</div>
);
}
}
export default AppHeader;
if (props.logoutFunc) ...
メイン部App.jsからlogoutFuncを受け渡された場合には、ログイン認証済みの状態なので、Logoutボタンを表示します。
<button onClick={handleLogout}>
Logoutボタンを押された場合には、handleLogoutメソッドを呼び出します。そしてhandleLogoutメソッド内では、メイン部App.jsから受け渡されたlogoutFuncを呼び出してログアウト処理を実行します。
if (props.logoutFunc) ... else ...
メイン部App.jsからlogoutFuncを受け渡されなかった場合には、ログイン未認証状態なので、Logoutボタンは表示しません。
コンテンツ部 (AppContents.js)
コンテンツ部にあたるAppContents.jsを次のように修正します。
import React from 'react';
import './AppContents.css';
// メイン表示領域
// props
// user: useAuth0()で取得したuser情報
function AppContents(props) {
// 画面表示処理
return (
<div className="AppContents">
<div>メイン表示領域</div>
<div>
<span>ユーザー名:</span><span>{props.user.name}</span>
</div>
</div>
);
}
export default AppContents;
コンテンツ部<AppContents>は、ログイン認証済みの場合にだけ表示されます。
Auth0から受け渡されたユーザ情報props.userにログインしたユーザ情報が格納されています。ここでは{props.user.name}としてユーザIDを表示しています。
動作確認
それでは実際に動かしてみます。authsample1ディレクトリ上で、Node.jsを起動します。
(authsample1ディレクトリ内で)
$ npm start
自動的にブラウザが起動します。もし起動しない場合には、http://localhost:3000/ にアクセスします。
最初はログイン認証できていない状態ですので、メイン部<App>でログインボタンを表示します。
ログインボタンを押下します。
すると、Auth0サイトにリダイレクトし、Auth0サイト上でログイン画面を表示します。
メールアドレスとパスワードには、ReactでOpenID Connectを実装する~その2で登録したユーザIDとパスワードを入力します。
正しいユーザIDとパスワードを入力すると、再び自サイト(localhost)にリダイレクトされ、認証後の画面を表示します。
Logoutボタンを押下すると、ログアウト処理が行われ、再び最初のログイン画面に戻ります。
次回はAuth0が提供するAPI(@auth0/auth0-react)を使う代わりに、一般的なOpenID Connect用APIであるreact-oidcを使ってログイン認証処理を実装してみます。
ReactでOpenID Connectを実装する~その4 react-oidcを使ってみる