RailsでGoogle AppsのOAuthを試す
Google Apps Premier EditionではOAuthが使えます。
Railsで試してみました。
基本的に以下の記事を参考にさせてもらっています。
RailsでTwitterのOAuthを試す | おいぬま日報
この記事のソースに対する修正点しか書いていないので、まずこの記事のサンプルを動かしてください。
これをGoogle Appsで動くように修正しました。
Google Calendarからカレンダー一覧を取得するだけです。
Google Appsのドメインの管理画面からConsumer keyを取得します
ドメインの管理画面から「高度なツール(Advanced tools)」をクリックして、以下の画面を表示します。
「Manage OAuth domain key」をクリックします。
※Premier EditionまたはEducation Editionではないとこのメニューは表示されません。
この画面からConsumer keyとConsumer secretを取得します。
「Allow access to all APIs」にチェックを入れると、Consumer secretが取得できた気がします。
app/controllers/index_controller.rbの修正
index_controller.rbを修正します。
コード中のConsumer keyとConsumer sercretとDomain nameを適切に設定します。
Domain nameはGoogle Appsに登録しているドメインです。
Google Appsでは、Consumer keyとDomain nameは同じです。
require 'oauth' require "rexml/document" class IndexController < ApplicationController def self.consumer OAuth::Consumer.new( "Consumer key", "Consumer secret", { :site => "https://www.google.com", :scheme => :header, :http_method => :post, :request_token_path => "/accounts/OAuthGetRequestToken", :access_token_path => "/accounts/OAuthGetAccessToken", :authorize_path => "/accounts/OAuthAuthorizeToken" } ) end def index end def oauth request_token = IndexController.consumer.get_request_token( {:oauth_callback => "http://#{request.host_with_port}/oauth_callback"}, :scope => "https://www.google.com/calendar/feeds/" ) session[:request_token] = request_token.token session[:request_token_secret] = request_token.secret redirect_to request_token.authorize_url(:hd => 'Domain name') 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, 'https://www.google.com/calendar/feeds/default/allcalendars/full', access_token, { :scheme => :header } ) case response when Net::HTTPSuccess @calendar_info = get_calendar_info(response.body) when Net::HTTPRedirection response = consumer.request( :get, response['Location'], access_token, { :scheme => :header } ) @calendar_info = get_calendar_info(response.body) else RAILS_DEFAULT_LOGGER.error "Failed to get user info via OAuth" flash[:notice] = "Authentication failed" redirect_to :action => :index return end end private def get_calendar_info(xml) doc = REXML::Document.new xml doc.elements.to_a('//entry/title') end end
app/views/index/oauth_callback.html.erbを修正
Twitterとはレスポンスが異なるので、修正します。
<html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>GoogleからOAuthで認証完了</title> </head> <body> <h3>カレンダー一覧</h3> <ul> <% @calendar_info.each{|cal| %> <li><%=cal.text%></li> <% } %> </ul> </body> </html>
修正ポイント
request_token = IndexController.consumer.get_request_token( {:oauth_callback => "http://#{request.host_with_port}/oauth_callback"}, :scope => "https://www.google.com/calendar/feeds/" )
で、scopeを指定します。どのAPIを使うかを明示する必要があります。
redirect_to request_token.authorize_url(:hd => 'Domain name')
でドメイン名を指定します。これをしないと、Google Appsのログイン画面ではなく、普通のGoogleのログイン画面に飛んでしまいます。
when Net::HTTPRedirection response = consumer.request( :get, response['Location'], access_token, { :scheme => :header } ) @calendar_info = get_calendar_info(response.body)
最初のアクセスでは302が返ってきたので、もう一回リクエストを投げてあげる必要があります。この際も認証情報を渡す必要があるので、OAuthのライブラリでリクエストを投げます。
動かしてみる
ruby script\server
で起動して、http://localhost:3000/にアクセスしてみます。
「OAuthで認証」をクリック
そのドメインのGoogle Appsへのログイン画面が表示されますので、ログインします。
Calendarへのアクセスの許可を求める画面が表示されます。「許可」をクリックします。
カレンダー一覧が表示されました。