Vue.全盛の中、社内メンバー向けのReactの簡単なチュートリアル。
シリーズ
- その1:create-react-appの簡単な使い方とファイル構成
- その2:簡単なページの作成(共通パーツ化含む)とreact-routernによるルーティング
- その3:簡易認証機能(ログイン・ログアウト)の追加(この記事)
その3の概要
- ログイン・ログアウト機能をつけ、ログイン済でなければサイトを見えなくします
- 会員ページや管理画面等での利用を想定したものです
- 認証処理は仮のものとします。
- 認証はlocalStorageにlogin=trueというようなフラグがあるかないかで判断するようにします
ログインページの追加
まずはログインページを作成します。
今回は見た目のみ作成し、ボタンをクリックしたらlocalStorageにlogin=trueとなるような情報を書き込み、Homeにリダイレクトするようにします。
Login.js
import React from 'react';
import { withRouter } from 'react-router-dom';
class Login extends React.Component {
handleLogin = () => {
localStorage.setItem("login", "true");
this.props.history.push("/");
}
render() {
return (
<div style={{ background: "#eee", height: 200, width: 300, margin: '100px auto', textAlign: 'center', padding: 30 }}>
<h3>ログイン</h3>
ID: <input type="text" style={{ marginTop: 10 }} /><br />
PW: <input tppe="text" style={{ marginTop: 10 }} /><br />
<button style={{ marginTop: 10 }} onClick={() => this.handleLogin()}>ログイン</button>
</div>
);
}
}
export default withRouter(Login);
認証機能の実装(仮)
次に認証機能を実装します。localStorageにlogin=trueのフラグ情報があればHomeを表示し、なければ/loginにリダイレクトさせる機能になります。
Auth.js
import React from 'react';
import { Redirect } from 'react-router-dom';
class Auth extends React.Component {
render() {
let loginStatus = localStorage.getItem("login");
if (loginStatus === "true") {
return this.props.children;
} else {
return <Redirect to="/login" />
}
}
}
export default Auth;
ログアウト機能の追加
ログアウト機能が無いのでナビゲーションにLogoutボタンを追加し、ログアウト機能を実装します。
ログアウトはlocalStorageのフラグ情報をlogin=falseとすることで実現させます。
Nav.js
import React from 'react';
import { NavLink, withRouter } from 'react-router-dom';
class Nav extends React.Component {
+ handleLogout = () => {
+ localStorage.setItem("login","false");
+ this.props.history.push("/");
+ }
render() {
return (
<nav style={{ background: "#666" }}>
<ul style={{ display: 'flex', listStyle: 'none' }}>
<li style={{ margin: 10 }}><NavLink exact to="/" style={{ color: "#fff", textDecoration: 'none' }} activeStyle={{ color: '#aaf' }}>Home</NavLink></li>
<li style={{ margin: 10 }}><NavLink exact to="/about" style={{ color: "#fff", textDecoration: 'none' }} activeStyle={{ color: '#aaf' }}>About</NavLink></li>
+ <li style={{ margin: 10 }}><span style={{ color: "#fff", cursor: 'pointer' }} onClick={() => this.handleLogout()}>Logout</span></li>
</ul>
</nav>
);
}
}
export default withRouter(Nav);
ルーティングの設定
では、上記が連携して動くようにApp.jsの記述を変更します。
<Auth></Auth>で囲まれた部分に認証がかかります。わかりやすいですね。
App.js
import React from 'react';
import { BrowserRouter, Route, Switch, NavLink } from 'react-router-dom';
//import screens
import Home from './screens/Home';
import About from './screens/About';
import Login from './screens/Login';
//Auth
import Auth from './Auth';
class App extends React.Component {
render() {
return (
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login} />
<Auth>
<Switch>
<Route exact path="/" component={Home} />
<Route exact path="/about" component={About} />
<Route render={() => (<p>Page not found.</p>)} />
</Switch>
</Auth>
</Switch>
</BrowserRouter>
);
}
}
export default App;
動作確認
yarn startさせて動作確認します。
まずはログイン。
そして、ログイン後のページ。
ログアウトが正常に機能しているかや、ログアウト時に/about等にアクセスした際、ブロックされるか(loginにリダイレクトされるか)等を確認しましょう。
その3のおさらい
- react-routerを利用した未認証・認証済み時の切り分けについておさらいしました。
予定
今後、下記のコンテンツを追加する予定。
- Reduxを利用した値、関数の共有
- Firebaseとの連携(Auth, Hosting, functionsを利用したForm設置等)
- Hostingにホスティングするのはこちらをどうぞ。
- .envの利用