oinume journal

Scratchpad of what I learned

RailsでTwitterのOAuthを試す

OAuthが前々から気になっていたので、RailsTwitterのOAuthを使うサンプルを作成しました。OAuthについてはここでは詳しく説明しませんが、

 

 

 

 

 

 

 

の記事がよくまとまっているので、目を通してみるとよいでしょう。OAuthを一言でいうと、サードパーティのアプリケーション(Consumer)をサービスプロバイダ側(Service Provider)で認可するという仕組みで、端的に言えばサードパーティ側でサービスプロバイダのアカウント情報を保持する必要がなくなるというメリットがあります。

 

たとえば、今回の例だとTwitter(=Service Provider)のデータを利用するので、Twitterから認可を受ける必要があります。これをOAuthという仕組みを使って、サンプルアプリケーション(=Consumer)ではTwitterのアカウント情報を一切入力させないようにします。

 

Twitter API WikiOAuth Example - Rubyという素晴らしいページがあるのですが、これが最新版の仕様に対応してなさそうなので、上げてみました。

 

railsやoauthなどのライブラリのインストール

必要なものは以下になるので、rubygemsでインストールしておきます。

 

 

 

 

  • oauth 0.3.5

 

 

 

 

 

 

$ sudo gem install rails

$ sudo gem install oauth

$ sudo gem install json

 

 

Twitterでアプリケーションを登録

サンプルを作る前にTwitterのOAuthのページでアプリケーションを登録します。

 

Twitterでアプリケーションを登録

 

Callback URLは http://localhost:3000/oauth_callback とか書くとエラーになるので、http://example.com/ のように適当なURLを記載しておきます。(実際にここで設定したURLがコールバックされるわけではありません)

 

全て記入して登録すると、Consumer keyとConsumer secretが発行されるのでこれを記録しておきます。後述する IndexController でこれらを使用します。

 

サンプル作成

サンプルアプリの雛形を作成します。

 

 

$ rails twitoauth

$ cd twitoauth

$ script/generate controller index

 

 

IndexControllerの作成

app/controllers/index_controller.rbを編集して、IndexControllerを実装します。Consumer key、Consumer secretは先ほどTwitterから発行されたものを使用してください。

 

 

require 'oauth'

require 'json'

 

class IndexController < ApplicationController

def self.consumer

OAuth::Consumer.new(

"Consumer key",

"Consumer secret",

{ :site => "http://twitter.com" }

)

end

 

def index

end

 

def oauth

# :oauth_callbackに認証後のコールバックURLを指定

# この場合だとこのコントローラー内の oauth_callback メソッドが実行される

request_token = IndexController.consumer.get_request_token(

:oauth_callback => "http://#{request.host_with_port}/oauth_callback"

)

session[:request_token] = request_token.token

session[:request_token_secret] = request_token.secret

# twitter.comで認証する

redirect_to request_token.authorize_url

return

end

 

def oauth_callback

consumer = IndexController.consumer

request_token = OAuth::RequestToken.new(

consumer,

session[:request_token],

session[:request_token_secret]

)

 

access_token = request_token.get_access_token(

{},

:oauth_token => params[:oauth_token],

:oauth_verifier => params[:oauth_verifier]

)

 

response = consumer.request(

:get,

'/account/verify_credentials.json',

access_token, { :scheme => :query_string }

)

case response

when Net::HTTPSuccess

@user_info = JSON.parse(response.body)

unless @user_info['screen_name']

flash[:notice] = "Authentication failed"

redirect_to :action => :index

return

end

else

RAILS_DEFAULT_LOGGER.error "Failed to get user info via OAuth"

flash[:notice] = "Authentication failed"

redirect_to :action => :index

return

end

end

end

 

 

完了したら、indexアクションに対応するViewである app/views/index/index.erb を作成します。これは単純に /oauth に飛ばすだけのテンプレートです。

 

 

 

 

 

OAuthのサンプル

 

 

OAuthで認証

 

 

 

 

config/routes.rb を修正

次に IndexController に定義されているアクションが呼び出されるようにURLとのマッピングをします。具体的には config/routes.rb の

 

 

map.connect ':controller/:action/:id'

map.connect ':controller/:action/:id.:format'

 

 

となっている箇所の上に下記を追記します。

 

 

map.root :controller => 'index'

map.connect ':action', :controller => 'index'

 

 

OAuthを試してみる

とりあえず9割方準備が整ったので、サーバを起動して http://localhost:3000/ にアクセスします。

 

 

$ script/server

 

 

OAuthで認証のリンクをクリックすると、下記のようにTwitterにリダイレクトされたでしょうか?(うまくリダイレクトされない場合は index_controller.rb の index アクションのコードに問題がある可能性が高いです)

TwitterでOAuth認証

 

ここでTwitterのアカウントを入力して"Allow"をクリックすると、「アプリに転送します」というメッセージが表示され、サンプルアプリに遷移します。具体的には、index_controller.rb のoauthアクション内のget_request_tokenメソッドで登録したコールバックURLにリダイレクトされています。

 

ただ、現状だとコールバック先の画面で使用するテンプレートファイルを作成していないため

 

 

Template is missing

Missing template index/oauth_callback.erb in view path app/views

 

 

というエラーになるので、次はこのテンプレートを作成します。

 

最後の仕上げ

/oauth_callback のテンプレートを下記の内容で作成します。やっていることは単純で、/account/verify_credentials.jsonAPIで取得した情報を表示しているだけです。

 

 

 

 

 

TwitterからOAuthで認証してもらったよ!

 

 

<%= @user_info['name'] %>さんの最新のつぶやき

<%= @user_info['status']['text'] %>

 

 

 

 

これを app/views/oauth_callback.rb として保存したら、もう一度 http://localhost:3000/ にアクセスして最初から認証をやり直します。下記のようにTwitterの情報が取得できれば、OAuthでの認証+APIの呼び出しは成功です。

 

OAuthでログインしてTwitterのデータを取得

 

まとめ

ライブラリを使えば少しの労力でOAuthでTwitterに認証してもらえることが伝わったでしょうか?OAuthを使えば、サービス側(Consumer側)でTwitterのアカウント/パスワードを保持しなくて済むので、よりユーザに安心を提供できるはずです。現状、コールバックURLを使う方法はPCのブラウザでしか実行できませんが、モバイルやデスクトップアプリのためにPINコードを発行する方法も用意されているので、より詳しく知りたい人は本家のドキュメントを読んでみると良いと思います。

 

[tmkm-amazon]4274068668[/tmkm-amazon]