ユーザログインが必要なウェブサービスを作りたいが、ユーザの心理的に新たなウェブサービスに対してユーザ名とパスワードを登録するのってハードルが高いと思う。そこで既存のサービスのアカウント情報を使ってログインできるようにしたい。
ここではTwitterの認証を使ってアカウント情報に紐付けるアプリを作ってみたい。アプリはHerokuを使ってデプロイする。言語はRuby、フレームワークはSinatraを使う。
Twitterへのアプリの登録
Twitterの認証を使えるようにするために、Twitterにアプリを登録する。
- Twitter Application Managementにアクセスして、
[Create New App] で新規アプリを登録する。
- アプリ名、説明、ウェブサイト、コールバックURL を登録する
- ウェブサイトとコールバックURLは適当に設定しておいて、Herokuでアプリをデプロイしてから 後でちゃんと設定する
- コールバックURLは必須マークが付いてないけど、設定しないと動かなかった
- コールバックURLはTwitterで認証が成功または失敗したときに呼び出される、アプリ側のURL となる
Sinatraでアプリの作成
実際にウェブアプリを作っていく。ここではシンプルにSinatraを使う。
source 'https://rubygems.org' |
require 'sinatra' |
<!DOCTYPE html> |
bundle install
で必要なライブラリをインストールして、bundle exec ruby app.rb
でサーバを起動させる。デフォルトだとローカルの http://localhost:4567/ でアクセスできる。
Twitter認証の呼び出し
TwitterのOAuthを使って認証をする。実際には gem の twitter_oauth を使う。
htmlで /request_token
へのリンクを表示して、アクセスされたら実際に認証の手順を進める。
gem 'twitter_oauth' # 追加 |
<a href="/request_token">Twitter Login</a> |
require 'twitter_oauth' |
- Sinatraの
before
フィルタを使って、TwitterOAuth::Clientを作成する /request_token
にget
でアクセスされた時、そのtwitter用のoauthクライアントのrequest_token
を呼び出してやる。:oauth_callback
に認証が成功または失敗した時に呼び出してもらうURLを指定する
- 後で認証結果を処理するときのために、セッションにリクエストのトークンとシークレットを 保存しておく
リンクをクリックするとアプリ情報を持ってTwitter側の request_token.authorize_url
にリダイレクトされ、おなじみの連携画面が表示される:
ここで連携を認証またはキャンセルすると、コールバックURL (/accesss_token) に戻ってくる。
認証結果の取得
Twitterから戻ってきた認証結果を取得する。
get '/access_token' do |
- コールバックURLのパラメータに渡された
oauth_verifier
が正しいかどうか、TwitterOAuth::Client#authrize
で認証する。 - 認証に成功したら
info['user_id']
にTwitterのユーザID、info['screen_name']
に名前、info['profile_image_url_https']
にアイコン画像のURLが入っているので、アプリ側で 使える。 - TwitterのAPIを使ってタイムラインを取得したりする場合にはアクセストークンとか アクセストークンシークレットを使う
Herokuにデプロイ
Herokuにデプロイできるようにするために、設定ファイルを追加する。
require 'bundler' |
Herokuコマンドでアプリの登録などを行う
heroku login
heroku create
git push heroku master
キーやシークレットを環境変数から取得し、ソースに含めないようにする
Twitterのアプリのコンシューマキーやシークレットをソースに書いていたけどそれはあまりよくないし、githubなどにアップロードしてしまうのは問題がある。そこでソースコードからは外して環境変数に入れて使えるようにする。
環境変数に入れるにはシェルで設定する
$ export CONSUMER_KEY="..." |
Sinatraアプリから参照するには ENV
を通して
key = ENV['CONSUMER_KEY'] |
とできる。
Herokuで使えるようにするには heroku config:add
で設定する:
$ heroku config:add CONSUMER_KEY="..." |
他
- Sinatraでセッション情報を
session
に保存するけど、enable :sessions
を指定しないと ちゃんと保存できない?ことがある。でも指定するとセッション情報をすべてをクッキーで送る? とかいう情報があるので、ちゃんとした方がいいかも。 - Twitterのアプリの設定画面に「Allow this application to be used to Sign in with Twitter」というチェックボックスがあるが、どういう項目かよくわからなかった