RubyでGoogleDrive APIを使用するためにアクセストークンを取得する

RubyのGoogleDrive Gemを使ってGoogleDriveをさわろうとしたところ、OAuthの認証でつまづいたのでそのメモします。

OAuth2.0の流れはこんな感じです。

  1. ClientIDとClientSecretを発行する
  2. 認証する
  3. アクセストークンを取得する
  4. リフレッシュトークンからアクセストークンを再取得する
  5. GoogleDrive gemを使ってみる

ClientIDとClientSecretを発行する

まずはプロジェクトを作成します。
https://cloud.google.com/console/project

APIsから「Drive API」と「Drive SDK」をONにします。

「Credentials」から「CREATE NEW CLIENT ID」から今回のプログラムで使う必要項目を取得します。

以上のような項目を選択

これでClientIDとClientSecretが作成されました。

認証する

ユーザーがAPIアクセスの許可を行い、Authorization codeを取得します。
これにはhttps://accounts.google.com/o/oauth2/authに以下のパラメータを付与したものにブラウザからアクセスします。

  • client_id:さきほど発行したClientID
  • redirect_uri:さきほど発行したRedirectURIs
  • scope:今回はGoogleDriveを使いたいので https://www.googleapis.com/auth/drive
  • response_type:”code”

よって以下のようなURLになります。

https://accounts.google.com/o/oauth2/auth
?client_id=8972549879287.apps.googleusercontent.com
&redirect_uri=http://localhost
&scope=https://www.googleapis.com/auth/drive
&response_type=code

このURLにアクセスすると認証画面になるので承認してください。
redirect_uriに設定したURLにcodeパラメータがついています。それがAuthorization codeになります。

アクセストークンを取得する

Authorization codeからアクセストークンを取得します。
https://accounts.google.com/o/oauth2/token にPOSTで以下のパラメータを送る必要があります。

  • client_id:最初に発行したClientID
  • client_secret:最初に発行したClientSecret
  • redirect_uri:最初に発行したRedirect URIs
  • grant_type: “authorization_code”
  • code: Authorization codeの値

POSTとして送るためcurlを使います。全体として以下のようなものになります。

$ curl -d client_id=[YOUR CLIENT ID] -d client_secret=[YOUR CLIENT SECRET] -d redirect_uri=[YOUR REDIRECT URI] -d grant_type=authorization_code -d code=[YOUR AUTHORIZATION CODE] https://accounts.google.com/o/oauth2/token

結果として以下のようなJSONが返ってきます。

{
    "access_token":"アクセストークン",
    "token_type":"Bearer",
    "expires_in":3600,
    "refresh_token":"リフレッシュトークン"
}

アクセストークンがAPIを使用するための鍵になります。

リフレッシュトークンからアクセストークンを再取得する

アクセストークンには有効期限(expires_in)があるため、有効期限が切れた場合、リフレッシュトークンからアクセストークンを再取得する必要があります。

https://accounts.google.com/o/oauth2/tokenにPOSTで以下のパラメータを送ればアクセストークンを再取得出来ます。

  • client_id:最初に発行したClientID
  • client_secret:最初に発行したClientSecret
  • refresh_token:リフレッシュトークン
  • grant_type:”refresh_token”

全体として以下のようなものになります。

$ curl -d client_id=[YOUR CLIENT ID] -d client_secret=[YOUR CLIENT SECRET] -d refresh_token=[YOUR REFRESH TOKEN] -d grant_type=refresh_token https://accounts.google.com/o/oauth2/token

これでアクセストークンを取得したときと同じJSONが返ってきます。その中のaccess_tokenの値が新しいアクセストークンになります。

GoogleDrive gemを使ってみる

それではアクセストークン、リフレッシュトークンをゲットすることが出来たので最後にgemを使ってみましょう。
詳しいAPI仕様は公式ドキュメントを見てください。

CLIENT_ID = "9874987-ljk4j45n5dhh485014849.apps.googleusercontent.com"
CLIENT_SECRET = "98FZqeIdnz8495"
REFRESH_TOKEN = "5/Qzjrnxhtn;lUidZ"

client = OAuth2::Client.new(
    CLIENT_ID, CLIENT_SECRET,
    :site => "https://accounts.google.com",
    :token_url => "/o/oauth2/token",
    :authorize_url => "/o/oauth2/auth")

# refresh_tokenでログイン
auth_token = OAuth2::AccessToken.from_hash(client,{:refresh_token => REFRESH_TOKEN, :expires_at => 3600})
auth_token = auth_token.refresh!

# ログイン完了!
session = GoogleDrive.login_with_oauth(auth_token.token)

以上でログインが終わりました。

最後に

これでGoogleAPIを自由に使うことが出来ました。
ただ、GoogleDriveにはOAuth2.0認証を簡単に行うためのコードが実はあるのです!(最初からそれ使えよ)
1回手動で大きな流れを理解したあとであれば以下のコードも理解出来ると思います。

client = OAuth2::Client.new(
    your_client_id, your_client_secret,
    :site => "https://accounts.google.com",
    :token_url => "/o/oauth2/token",
    :authorize_url => "/o/oauth2/auth")
auth_url = client.auth_code.authorize_url(
    :redirect_uri => "http://example.com/",
    :scope =>
        "https://docs.google.com/feeds/ " +
        "https://docs.googleusercontent.com/ " +
        "https://spreadsheets.google.com/feeds/")

# 表示されるURLをブラウザで開く
print auth_url

print "authorization code:"
authorization_code = gets.chomp

auth_token = client.auth_code.get_token(
    authorization_code, :redirect_uri => "http://example.com/")
session = GoogleDrive.login_with_oauth(auth_token.token)

また、scopeで注意しなければならないこととしては、

  • scopeを複数連ねる場合はURLの最後に半角スペースを挿入しなければならない

ということです。上記のRubyのコードでもよくみるとscopeのURLの最後に半角スペースが入っているのがわかると思います。
僕はここが理解出来ていなくて1時間くらい無駄にしました(´・ω・`)

ということでこれでもう忘れても大丈夫!お役に立てれば幸いです。

ある程度Rubyが出来るようになったらこれ。頑張ります。

メタプログラミングRuby

posted with amazlet at 14.01.09
Paolo Perrotta
アスキー・メディアワークス
売り上げランキング: 19,124