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

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

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

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

はじめに

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

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

Twitter Developerにアプリ登録

Twitter Developer

これについては上記のURLにアクセスしてアプリを登録してください。
アプリ名とコールバックURLを登録したら、Consumer Key (API Key)とConsumer Secret (API Secret)がもらえます。
詳しくは書きません、ググればこれはたくさん書いてあります。

oauth-15

動作イメージ

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

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

oauth-1

oauth-12

oauth-11

oauth-5

ステップ1(Javascript、Ajax)

まずは
まずはTwitterのOAuth用URLの取得のためのRails API(自作)呼び出し。
Reactの書き方なので、functionらしくないですが・・・ただのfunctionだと思ってソースを見てください。

API呼び出しの結果、OAuth用のURLが得られるので、window.openする感じです。
ポップアップというか別タブでTwitterのOAuth画面が開きます。
で、window.openしたあとは setTimeoutで1秒おきにウィンドウが閉じたかどうかをチェックします。

ステップ1.5(Rails)

ステップ1から呼び出されるRailsのソース。
CONSUMER_IDとCONSUMER_SECRETを用いて、OAuth用のURLを取得し、JSONで結果を戻します。

ステップ2(Javascript)

ステップ1のソースのWindow呼び出しのところだけを抜粋。
RailsのAPIで戻ってきた認証用URLを引数にして window.open。

ステップ3

ここはプログラムする必要なしです。TwitterのOAuthの画面で
純粋に認証&許可をしてもらいます。

ステップ4(Rails)

Twitter側の認証と許可の処理が終わると、ステップ1.5で指定したコールバックURLに制御が戻ってきます。
テスト環境ですのでRailsのデフォルト http://localhost:3000 でサーバーが立ち上がっていて、
コールバックURLは http://localhost:3000/oauth_twitter です。

では、Railsの方の実装を見てみましょう。
最初にCONSUMER_IDとCONSUMER_SECRETを用いて、トークンを作成します。
さらに、パラメーターで渡ってきた、 oauth_tokenとoauth_verifierを使って
アクセストークンを得ます。
最後に得られたアクセストークンを使ってAPIアクセスし、ユーザー情報を得ます。

で、cookiesに得られた情報をセットして、このメソッドを抜けます。

cookies[:oauth_token] = params[:oauth_token]
cookies[:twitter_uid] = user_info[“id”]
cookies[:screen_name] = user_info[“screen_name”]

RailsのGemfileに以下の3つのgemを追加します。

SPAをサーブしているサーバーとAPIをサーブしているサーバーが別物になるので、
クロスドメインなAPIアクセスとなるため、API側でそれを許可する必要があります。
gem rack-cors でそれに対応できます。で、対応するためにapplication.rbを
以下のように書き換えます。 本番ではoriginsは「*」ではなく、ちゃんと特定のドメイン名を入れるべし。

config/application.rb

ステップ5(RailsのJavascript)

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

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

ステップ6(SPAのJavascript)

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

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

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

oauth-14

あとがき

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


About the author:

Related Posts

Leave a comment

Back to Top