rubyのoauth2を使ってfacebookとのOAuth連携を試みてみた。環境は以下の通り。
- ruby: 1.9.2p180
- oauth2: 0.5.2
まずは、facebook認証のURLを生成するコードを書いてみる。
require 'oauth2'
site = "https://graph.facebook.com"
token_url= "/oauth/access_token"
key="xxxx" # facebookのAPP ID
secret="xxx" # facebookのAPP SECRET
callback_url="http://xxx.com/" # callbackしてほしいURL
#インスタンス作成
client = OAuth2::Client.new(key,secret,:site => site,:token_url => token_url)
#URL作成
url = client.auth_code.authorize_url( :redirect_uri => callback_url)
#URL表示
puts url
これで出来たURLでアクセスすると、facebookのログイン画面が出るので、そこでログインすると次のようなLocationを指定したリダイレクト要求のレスポンスが返ってくる。
Location: (callbackしほしいURL)/?code="(認証コード)"
次に認証コードを使って、tokenを取得するスクリプトを書いてみる。
require 'oauth2'
site = "https://graph.facebook.com"
token_url= "/oauth/access_token"
key="xxxx" # facebookのAPP ID
secret="xxx" # facebookのAPP SECRET
callback_url="http://xxx.com/" # callbackしてほしいURL
code ="xxxx" # 前のスクリプトで取得したcode
#インスタンス作成
client = OAuth2::Client.new(key, secret, :site => site, :token_url => token_url)
#tokenの取得
access_token = client.auth_code.get_token( code, { :redirect_uri => callback_url })
#token表示
puts access_token.token
これを実行すると、以下のようなエラーがでた。
/usr/local/lib/ruby/gems/1.9.1/gems/oauth2-0.5.2/lib/oauth2/client.rb:129:in `get_token': OAuth2::Error (OAuth2::Error)
まったくわからなかったので、ソースを見ると、問題の個所はこのようになっており、
response = request(options[:token_method], token_url, opts)
raise Error.new(response) if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
ここのoptions[:raise_errors]というのがtrueのため例外を飛ばしていることが分かった。
原因を調査していると、githubの掲示板にこのことが書いてあり、acvwilsonさんが解決策を書いてくれている。
まとめると「facebookからのレスポンスの形式(=が入っているやつ)に対応できていないので、以下のコードを追加してパーサを対応させてくれ。」とのこと
OAuth2::Response.register_parser(:text, 'text/plain') do |body|
key, value = body.split('=')
{key => value}
end
これを追加するとうまく動いた!