概要
Webアプリを作るとき、最近は画面の構成はSPAでやるのが主流です。
SPAでのコンテンツの配置はこちらの記事で書きました。
SPAの静的ファイルのデプロイの仕方
SPAの構成のログイン制御の仕方はこちらの記事でざっくり書きました。
SPAでのログイン処理のやりかた
play2でSPAのコンテンツを配信するやり方はこちらに書きました。
Play2でのSPAコンテンツの配信の仕方
Play2で認証の処理をするやり方をこちらに書きました。
Play2-authを使ってみる - 認可/Authorization編
さて、それらを組み合わせて、play2で認証ありのSPAをどう扱うかについてまとめていきます。
環境
- Play 2.5
- React.js 15.x
- react-router(フロント側でのルーティング機構)
ソースコードはこちら。
ゴール
- 認証はサーバー側でAPIを介して行う
- ルーティングは全てjs側で行う
- APIアクセス時に、ログイン・権限の有無を確認できる
- ログインされてなければログイン画面にリダイレクトさせる
- 権限がなければ、それっぽいアラートを出す。
- ログイン画面読み込み時に、既にログイン済みならホーム画面へリダイレクトさせる
- 他の画面読み込み時に、未ログインならログイン画面へリダイレクトさせる
手順
- サーバーサイドのルーティングを用意する
- フロントのコンテンツを配置する
- 動作確認する
とりあえず動かして様子を見たい方は、「動作確認する」から読んで頂ければと思います。
サーバーサイドのルーティングを用意する
-> /api api.Routes
# static file
GET /public/*file controllers.Assets.versioned(path="/public", file: Asset)
# login/logout
GET /authentication/login/:userId/:password controllers.auth.AuthenticateController.login(userId: String, password: String)
GET /authentication/logout controllers.auth.AuthenticateController.logout
# html
GET /login controllers.HomeController.login
GET / controllers.HomeController.index
GET /*path controllers.HomeController.indexAll(path)
GET /authorize/admin controllers.auth.AuthorizeController.checkAdminRole
GET /authorize/normal controllers.auth.AuthorizeController.checkNormalRole
ログイン処理は、面倒なのでgetでできるようにしています。本番では真似しないよう。。。
説明は省略しますが、ログイン時の流れとしては、
-
/login
でログイン画面を表示する。 -
/public/*file
でjsなどを持ってくる -
/authentication/login/:userId/:password
でログインする -
/api//authorize/admin
などへアクセスしてみて、権限管理を確かめる
という流れになります。
フロントのコンテンツを配置する
最終的なコードはこちらを見てください。
https://github.com/uryyyyyyy/play2sample/tree/play2-spa-auth/webConsole/front
再掲となりますが、こちらにまとめてあります。
動作確認する
コードを用意。
https://github.com/uryyyyyyy/play2sample/tree/play2-spa-auth
また、sbtとnodeが必要です。
# SPAのルートディレクトリへ移動
cd webConsole/front
# フロントのビルド
npm install
npm run build:prod
# webConsoleのルートディレクトリへ移動
cd ../
# フロントのコードをplayのpublicに配置
sh deployFront.sh
# プロジェクトルートに移動
cd ../
# playパッケージング
sbt webConsole/dist
# パッケージされたものを実行
cd webConsole/target/universal/
unzip play2sample-main-1.0.zip
cd play2sample-main-1.0/
chmod 700 ./bin/play2sample-main
./bin/play2sample-main
これで、http://localhost:9000
につなげるようになります。
(以降の動作は、js側でalertを出して確認する形にしています。アラートが出ないなどの場合はブラウザ設定を確認してください。)
ログインしてなければログイン画面に戻ることを確認
http://localhost:9000
にアクセスする。
すると、ホーム画面はログイン済みでないと開けない設定なので、「認証に失敗しました」のアラートの後でログイン画面にリダイレクトする。
ログインしたあとはログイン画面にリダイレクトされないことを確認
http://localhost:9000/login
で、「login Normal」でログインする。
するとhttp://localhost:9000
に飛びます。
以降、セッションが有効な期間(デフォルトでは1時間)の間はリロードしてもホーム画面のままです。
違うパス(http://localhost:9000/sample
)に繋いでみてもちゃんとindex.htmlが読まれて、react-routerによってコンテンツが出てきていることが確認できます。
また、http://localhost:9000/login
に繋ぎに行くと、「認証済みです」のアラートの後でホームに飛ばされます。
権限制御できていることを確認(normal権限)
「normal API」を叩くと、「success」が返ってくることを確認します。
また、「admin API」を叩くと、許可されてない動作なので403が返り、ホーム画面にリダイレクトされます。
ログアウトするとログイン画面しか開けなくなることを確認
「logout」ボタンを押すと、セッショントークン(cookie)が破棄されます。
すると、初回時と同様にホーム画面にはアクセスできなくなります。
権限制御できていることを確認(admin権限)
http://localhost:9000/login
で、「login Admin」でログインする。
「normal API」も「admin API」も「success」が返ってくることを確認します。
先ほどのnormalログインとは違う挙動になったことがわかると思います。
まとめ
ここにたどり着くまで、たくさんの記事を書いてきました。
何かご質問や不明点があればお気軽にコメントください。