monolithic kernel

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

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)

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

ユーザの認証・許可

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

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

codeの受け取り

ユーザによる認証が完了すると、リダイレクトによってredirect_uriが呼び出されます。この時、引数としてアクセストークンの取得に必要となるcodeが付加されています。 例えばredirect_uriが”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