ReactでSPAを作り、Google認証(OAuth)でログインする。バックエンドはRails

ReactでSPAを作り、Google認証(OAuth)でログインする。バックエンドはRails

ReactでSPAを作り、Google認証(OAuth)でログインする。バックエンドはRails

ReactでSPAを作り、Google認証(OAuth)でログインする。バックエンドはRails へのコメントはまだありません

はじめに

ReactでSPAを作ることになって、ログイン認証にメール&パスワードの認証に加えて、
GoogleやTwitter認証も加えたくなった時、どうすればよいかわからなかった。
バックエンドはRailsだが、あくまでAPIサーバー的な立場なので メジャーなomniauth
なんかは使えそうにない。。。
あれこれ悩みながらなんとか動くところまでたどり着いたので、やり方を公開。

React+Reduxの環境なんですが、そこまで立ち入ると話がややこしくなるので、
実装のエキス部分だけを記載してみます。

Google Developer Consoleにアプリ登録

Google Developers Console

これについては上記のURLにアクセスしてアプリを登録してください。
アプリ名とコールバックURLを登録したら、クライアントIDとクライアントシークレットがもらえます。
詳しくは書きません、ググればこれはたくさん書いてあります。

oauth-7

動作イメージ

デザインはしょぼいですが、こんな感じのログイン画面。
GoogleかTwitterで認証してログインしてね、というもの。
今回はGoogleについてのみ取り上げます。

Google+でログインをクリックすると、Googleが用意しているOAuth用の画面が表示されて、
Googleのユーザー名とパスワードを入れて、最後に今回作るアプリ(SPA)へのアクセス許可画面が表示され、
許可すると、SPAアプリにログイン出来るというもの。

oauth-1

oauth-2

oauth-3

oauth-4

oauth-5

ステップ1(Javascript)

まずはGoogleのOAuth画面の呼び出し。
Reactの書き方なので、functionらしくないですが・・・ただのfunctionだと思ってソースを見てください。

https://accounts.google.com/o/oauth2/auth に必要なパラメーターをざーっとつけて
window.openする感じです。
ポップアップというか別タブでGoogleのOAuth画面が開きます。
で、window.openしたあとは setTimeoutで1秒おきにウィンドウが閉じたかどうかをチェックします。

ステップ2(Rails)

ステップ1でウィンドウを開くときのURLにコールバック用のURLを設定していますので、Google側の認証が終われば、
コールバックURL(自分で実装するアプリ)に制御が戻ってきます。
テスト環境ですのでRailsのデフォルト http://localhost:3000 でサーバーが立ち上がっていて、
コールバックURLは http://localhost:3000/oauth_google です。

では、Railsの方の実装を見てみましょう。
最初にステップ1でGoogleの認証画面を呼び出した時のステート(ランダム文字列)と
Googleさんが戻してきたステートが一致するか確認します。
OKならば、Developer Consoleで登録した、CLIENT_IDとCLIENT_SECRETを使い、
トークンを取得しに行きます。

最後に得られたトークンを使って、API呼び出しをしてGoogleに登録されている情報を読み出します。
で、cookiesに得られた情報をセットして、このメソッドを抜けます。

cookies[:google_code] = params[:code]
cookies[:email] = email
cookies[:google_uid] = api_result[“user_id”]

ステップ3(RailsのJavascript)

OauthControllerのgoogleメソッドで処理をしたので、普通に処理が終われば、ポップアップ画面には
そのメソッドに対応するビューが表示されます。
なので、対応するビューは作るのですが、あくまでダミーで結構です。
そもそも、ポップアップ(別タブ)でGoogle認証が開いていて、認証が終わればポップアップは閉じてほしい
はずですので・・・

で、assets/javascripts 配下に以下のようなJavaScript(CoffeeScriptではない)を作ります。
ファイル名はなんでもいい。
で、ここでする処理は、ダミーのビューが表示された時にそのhrefをチェックして、
認証終了のダミービューだと判定できたら、window.closeしてやるというものです。

ステップ4(SPAのJavascript)

最後にクライアントサイドです。window.openの時にsetTimeoutで呼ばれるメソッドです。
windowLogin.closedの状態を1秒間隔でチェックし、Googleの認証画面が閉じたら
alertに認証で得られた情報をクッキーから表示します。(別に表示する必要はないのですが・・・)
で、認証が通ったと判定できたら、アプリのトップページなどへジャンプしてやります。

あとはSPAなのでAPIサーバーへアクセスするたびにおそらくユーザー認証も必ずすることになると思うので、
APIを呼ぶたびに、ここで得られた情報を付与してやるイメージでしょうか・・・

本題とはそれますが、setTimeoutで引数をつけたfunctionを呼びたいときは 無名関数とする
のがルールのようです。

oauth-6

あとがき

あっさりと説明しちゃいましたが、理屈がわかるまで結構時間がかかりました。
SPAでSNS認証するならどうすりゃいいんだという情報が、以外になくて・・・
あちこち読み漁って、なんとか形になりました。
何かの参考になればと・・・・


About the author:

Related Posts

Leave a comment

Back to Top