monolithic kernel

RubyでロケタッチのAPIを呼び出してみる

September 18, 2011

    16日にデベロッパー登録が不要になったばかりのロケタッチAPIをRubyから呼び出してみます。

    インストール

    ロケタッチAPIは認証にOAuth2を利用しているので、利用するためにgemをインストールします。ただ、9/18時点でgem installして入るバージョンには問題があるため、Bundlerを利用してGitHubにある最新バージョンを利用します。

    Gemfileに以下の行を追加してbundle installを実行します。

    gem 'oauth2', :git => 'https://github.com/intridea/oauth2.git'

    Client IDの取得

    アプリケーション管理ページでアプリケーションを登録し、Client IDとClient Secretを取得します。

    認証

    ここではWebアプリケーションでロケタッチAPIを利用するときの認証について説明します。

    認証は以下の流れで行います。

    1. authorize_urlの生成
    2. ユーザの認証・許可
    3. codeの受け取り
    4. アクセストークンの取得

    最後に取得するアクセストークンを使ってAPIの呼び出しを行います。

    authorize_urlの生成

    ユーザが認証の操作を行うページのURL(authorize_url)を生成します。

    require 'oauth2'
    
    client = OAuth2::Client.new(
      'YOUR_CLIENT_ID',
      'YOUR_CLIENT_SECRET',
      :site => 'https://api.loctouch.com',
      :authorize_url => 'https://tou.ch/oauth2/authenticate',
      :token_url => 'https://tou.ch/oauth2/token')
    
    redirect_uri = 'YOUR_REDIRECT_URI'
    
    authorize_url = client.auth_code.authorize_url(:redirect_uri => redirect_uri)

    authorizeurl/tokenurlはurlですがredirect_uriはuriになっています。なんでこんな仕様なのかよくわかりませんが、ミスしやすいので要注意。

    ユーザの認証・許可

    生成したauthorize_urlにリダイレクトします。Sinatraであれば以下のような記述でリダイレクトできます。

    get '/auth/authorize' do
      ...
      redirect authorize_url
    end

    codeの受け取り

    ユーザによる認証が完了すると、リダイレクトによってredirecturiが呼び出されます。この時、引数としてアクセストークンの取得に必要となるcodeが付加されています。 例えばredirecturiが”http://example.com/auth/callback”に設定されている場合、“http://example.com/auth/callback?code=…”にリダイレクトされます。

    get '/auth/callback' do
      code = params[:code]
      ...
    end

    アクセストークンの取得

    先ほどのcodeを使ってアクセストークンを取得します。戻り値のアクセストークンオブジェクトを利用してAPIを呼び出します。

    header_format = 'OAuth %s'
    
    access_token = client.auth_code.get_token(
      code, 
      { :redrect_uri => redirect_uri },
      { :header_format => header_format })
    
    token = access_token.token

    access_token.tokenの返す値を保存しておけば、再度認証を行うことなくAPI呼び出しが可能です。以下のコードでは、保存しておいたトークンからアクセストークンオブジェクトを生成しています。

    access_token = OAuth2::AccessToken.new(client, token, :header_format => header_format)

    API呼び出し

    getメソッドでGET、postメソッドでPOSTリクエストをそれぞれ実行します。

    自分の情報を取得する/v1/users/@selfであれば以下のような感じ。戻り値はOAuth2::Responseクラスのオブジェクトですが、そのままparsedメソッドを呼んであげるとjsonをパースしてHashとして返してくれます。

    p access_token.get('/v1/users/@self').parsed

    パラメータが必要な場合は、以下のように第2引数のハッシュにparamsを渡します。

    p access_token.get('/v1/users/search', :params => { :query => '...' }).parsed

    APIの詳細についてはAPI一覧をご覧ください。

    サンプル

    簡単なサンプルを作成してみました。Ruby 1.9.2で動作を確認しています。

    $ gem install bundler
    $ bundle install
    $ bundle exec rackup

    Gemfile

    source 'http://rubygems.org'
    
    gem 'oauth2', :git => 'https://github.com/intridea/oauth2.git'
    gem 'rack'
    gem 'sinatra'

    config.ru

    # -*- coding: utf-8 -*-
    require 'bundler/setup'
    require_relative 'app'
    run Application

    app.rb

    # -*- coding: utf-8 -*-
    require 'oauth2'
    require 'rack'
    require 'sinatra/base'
    
    class Application < Sinatra::Base
    
      configure do
        set :session, false
        use Rack::Session::Cookie, :secret => '...'
      end
    
      helpers do
        def client
          @client ||= OAuth2::Client.new(
            'YOUR_CLIENT_ID',
            'YOUR_CLIENT_SECRET',
            :site => 'https://api.loctouch.com',
            :authorize_url => 'https://tou.ch/oauth2/authenticate',
            :token_url => 'https://tou.ch/oauth2/token')
        end
    
        def redirect_uri
          'YOUR_REDIRECT_URI'
        end
    
        def header_format
          'OAuth %s'
        end
      end
    
      get '/' do
        redirect '/auth/authorize' unless session[:token]
        access_token = OAuth2::AccessToken.new(client, session[:token], :header_format => header_format)
        result = access_token.get('/v1/users/@self')
        content_type 'application/json', :charset => 'UTF-8'
        result.body
      end
    
      get '/auth/authorize' do
        redirect client.auth_code.authorize_url(:redirect_uri => redirect_uri)
      end
    
      get '/auth/callback' do
        not_found unless params[:code]
        access_token = client.auth_code.get_token(
          params[:code], 
          { :redirect_uri => redirect_uri },
          { :header_format => header_format })
        session[:token] = access_token.token
        redirect '/'
      end
    
    end
    
    run Application