ReactでOpenID Connectを実装する~その3
今回は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 authsample1Auth0が提供するライブラリ(@auth0/auth0-react)をインストールします。 $npm install @auth0/auth0-reactトップ画面(index.js)トップ画面にあたるindex.jsを次のように修正します。 importReactfrom'react'; importReactDOMfrom'react-dom'; import{Auth0Provider}from'@auth0/auth0-react'; import'./index.css'; importAppfrom'./App'; importreportWebVitalsfrom'./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 />全体がログイン認証の制御範囲になります。domainAuth0の設定情報で記載されていたDomainを設定します。clientIdAuth0の設定情報で記載されていたClient IDを設定します。audienceAuth0のAPI設定で記載されていたIdentifierのURL文字列を設定します。domain, clientId, audienceの値がAuth0管理画面で表示されている値が異なっているとうまく接続できないため慎重に入力しましょう。メイン部(main.js)メイン部分にあたるmain.jsを次のように修正します。 importReactfrom'react'; import{useAuth0}from'@auth0/auth0-react'; importAppHeaderfrom'./AppHeader'; importAppContentsfrom'./AppContents'; import'./App.css'; functionApp(){ //Auth0が提供する認証用定義 const{ isLoading, isAuthenticated, error, user,//ユーザー情報(TUser型) loginWithRedirect,//Auth0にログイン画面を表示するよう要求 logout,//Auth0に現在のユーザをログアウトするよう要求 }=useAuth0(); //Auth0への接続処理中の場合 if(isLoading){ return( <divclassName="App"> <divclassName="AppHeader"> <AppHeader/> </div> <divclassName="AppContents"> Auth0を利用した認証処理中... </div> </div> ); } //Auth0で認証エラー発生した場合 if(error){ return( <divclassName="App"> <divclassName="AppHeader"> <AppHeader/> </div> <divclassName="AppContents"> 認証エラー発生({error.message}) </div> </div> ); } //Auth0で正常に認証できた場合(→ログイン後の画面を表示する) if(isAuthenticated){ return( <divclassName="App"> <divclassName="AppHeader"> <AppHeaderlogoutFunc={logout}/> </div> <divclassName="AppContents"> <AppContentsuser={user}/> </div> </div> ); //認証前の画面表示(→ログインボタンを表示する) }else{ return( <divclassName="App"> <divclassName="AppHeader"> <AppHeaderlogoutFunc=""/> </div> <divclassName="AppContents"> <buttononClick={loginWithRedirect}>ログイン</button> </div> </div> ); } } exportdefaultApp;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を次のように修正します。 importReactfrom'react'; import'./AppHeader.css'; functionAppHeader(props){ //ログアウトボタン押下時 consthandleLogout=(event)=>{ console.log(event.target.value); props.logoutFunc({returnTo:window.location.origin}); } //ログアウト関数が指定されている場合(→ログアウトボタンを表示) if(props.logoutFunc){ return( <divclassName="AppHeader"> <span></span> <span>OpenIDConnectSample1</span> <spanclassName='right'> <buttononClick={handleLogout}>Logout</button> </span> </div> ); //ログアウト関数が指定されていない場合(→ログアウトボタンは非表示) }else{ return( <divclassName="AppHeader"> <span></span> <span>OpenIDConnectSample1</span> </div> ); } } exportdefaultAppHeader;if(props.logoutFunc) ...メイン部App.jsからlogoutFuncを受け渡された場合には、ログイン認証済みの状態なので、Logoutボタンを表示します。<buttononClick={handleLogout}>Logoutボタンを押された場合には、handleLogoutメソッドを呼び出します。そしてhandleLogoutメソッド内では、メイン部App.jsから受け渡されたlogoutFuncを呼び出してログアウト処理を実行します。if(props.logoutFunc) ... else ...メイン部App.jsからlogoutFuncを受け渡されなかった場合には、ログイン未認証状態なので、Logoutボタンは表示しません。コンテンツ部(AppContents.js)コンテンツ部にあたるAppContents.jsを次のように修正します。 importReactfrom'react'; import'./AppContents.css'; //メイン表示領域 //props //user:useAuth0()で取得したuser情報 functionAppContents(props){ //画面表示処理 return( <divclassName="AppContents"> <div>メイン表示領域</div> <div> <span>ユーザー名:</span><span>{props.user.name}</span> </div> </div> ); } exportdefaultAppContents;コンテンツ部<AppContents>は、ログイン認証済みの場合にだけ表示されます。Auth0から受け渡されたユーザ情報props.userにログインしたユーザ情報が格納されています。ここでは{props.user.name}としてユーザIDを表示しています。動作確認それでは実際に動かしてみます。authsample1ディレクトリ上で、Node.jsを起動します。 (authsample1ディレクトリ内で) $npmstart自動的にブラウザが起動します。もし起動しない場合には、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でOpenIDConnectを実装する~その4 react-oidcを使ってみる