Consumer key を取得して OAuth 開発をはじめよう
このドキュメントでは、はてなの OAuth 対応 API を使ったアプリケーションを開発するための準備の手順を説明します。本ドキュメントでは Web サーバーで動作する Web アプリケーションを例に説明しますが、ユーザーの元に配布して実行されるアプリケーションでも同様の方法で対応できます。
1. アプリケーションを登録して consumer key を取得する
まずは開発するアプリケーションをはてなに登録し、 OAuth アクセスに利用する consumer key、 consumer secret を取得しましょう。はてなは consumer key と consumer secret によってアクセス元のアプリケーションを区別し、ユーザーごとのアクセス許可の有無を管理しています。アプリケーションは何個でも無料で登録できます。
1.1. はてなIDを取得する
アプリケーションを登録するためにははてなID登録 (はてなユーザー登録) が必要です。はてなIDをまだお持ちでない方は登録してください。
既にはてなIDをお持ちの方は、はてなIDでログインしてください。以後の操作はログイン状態で行ってください。
1.2. 必要事項を記入してアプリケーションを登録する
OAuth 開発者向け設定ページを開きます。利用上の注意が表示されますので、ご同意いただいた上で必要事項を記入してアプリケーションを登録してください。アプリケーション登録には審査等はなく、登録直後からご利用いただけます。
OAuth 開発者向け設定ページでは、アプリケーションの名前や Web サイトの URL、ロゴ画像を指定することができます。これらは、ユーザーに OAuth を用いたアクセス許可を求める際に表示されるので、わかりやすく正確にご記入ください。虚偽の内容や誤解を招く表現などを含む登録は、利用規約に基づき事前の通告なく利用停止とすることがあります。
アプリケーションの登録は無料です。開発用と実サイト用など、必要に応じて複数個ご登録いただいてもかまいません。
1.3. Consumer key を確認する
OAuth 開発者向け設定ページには、登録されている各アプリケーションの consumer key と consumer secret が掲載されています。これらは以降の手順で OAuth を利用するプログラム中で使いますので、手元に控えておきましょう。consumer secret は他人に漏らさないように注意しましょう。
2. OAuth によってユーザーからアクセス許可を得る
はてなでの OAuth 認証は OAuth プロトコルのバージョン1.0a に従っています。OAuth 認証の詳しい流れや認証の方法についてはRFC 5849 - The OAuth 1.0 Protocol (英語) や後述のサンプルプログラムをご覧ください。ここでは簡単な流れとはてな固有のパラメータについて解説します。
2.1. Request token を取得する
まず認証用 URL にアクセスするために必要なリクエストトークンを取得します。OAuth の仕様で定義されたパラメータに加えて scope
というパラメータを指定します。 scope
には read_public
(公開情報の読み取り) や write_private
(非公開情報の書き込み) などがあり、はてなの OAuth 対応 API にはそれぞれ利用に必要な scope が定められています。利用したい API に対応した scope を指定して下さい。
Request token の取得URLは https://www.hatena.com/oauth/initiate になります。典型的なリクエスト・レスポンスは次のようになります。
# HTTPS
POST /oauth/initiate HTTP/1.1
Host: www.hatena.com
Authorization: OAuth realm="",
oauth_callback="oob",
oauth_consumer_key="yTVGWKqa6OiH5A%3D%3D",
oauth_nonce="0c670efea71547422662",
oauth_signature="lvQC7AXTRIaqxbjwVGgPlYuNaaw%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1291689730",oauth_version="1.0"
Content-Type: application/x-www-form-urlencoded
Content-Length: 33
scope=read_public%2Cread_private
HTTP/1.1 200 OK
Content-Type: application/x-www-form-urlencoded
oauth_token=QB%2FfqbXTpFB1GQ%3D%3D&
oauth_token_secret=M1xSNaj0mw0J%2Bksk0k7WpZiGNP4%3D&
oauth_callback_confirmed=true
(見やすさのために改行を挿入しています)
oauth_token_secret
は他人に漏らさないように注意しましょう。
Request token の取得時に指定できる scope はアプリケーションによって異なります。アプリケーションを登録をした時点で read_public
などの scope は既に利用できます。アプリケーションが利用可能な scope の確認や追加は登録済みのアプリケーションの一覧から行えます。 Scope はリクエスト例のようにカンマ (%2C
にエスケープされています。) で区切って複数指定することもできます。
2.2. 認証用URLにリダイレクトする
次にユーザーからはてなのリソースへのアクセス許可を得るために、ユーザーを一度はてなへリダイレクトする必要があります。ユーザーのデバイスによって次の表の URL にユーザーをリダイレクトすることを推奨します。
PC | https://www.hatena.ne.jp/oauth/authorize |
---|---|
スマートフォン | https://www.hatena.ne.jp/touch/oauth/authorize |
携帯電話 | https://www.hatena.ne.jp/mobile/oauth/authorize |
ユーザーをリダイレクトするときには 2.1. で取得した request token をパラメータとして付与して下さい。次のような URL になります。
https://www.hatena.ne.jp/oauth/authorize?oauth_token=QB%2FfqbXTpFB1GQ%3D%3D
リダイレクト先のページでは consumer や scope の情報が表示され、ユーザーはアクセスを許可するか拒否するかを選択します。
2.3. Access token を取得する
OAuth 対応 API の利用に必要な access token を取得します。 access token の取得には oauth_verifier
という確認コードが必要になります。 2.2. で ユーザーがアクセスを許可した場合ははてなはユーザーを 2.1. の oauth_callback
で指定されたURLに oauth_verifier
パラメータを付けてリダイレクトします。また URL の代わりに "oob" が指定されていた場合は `oauth_verifier の値をユーザーに表示しますので、ユーザーに入力を指示して下さい。
https://www.hatena.com/oauth/token へ取得した verifier を含むリクエストを送信することでアクセストークンが取得できます。典型的なリクエスト・レスポンスは次のようになります。
# HTTPS
POST /oauth/token HTTP/1.1
Host: www.hatena.com
Authorization: OAuth realm="",
oauth_consumer_key="yTVGWKqa6OiH5A%3D%3D",
oauth_nonce="83600f5f92b5c5a62caf",
oauth_signature="%2Fq%2B9Uzzat1A2WoGdGW7SZoeiUfg%3D",
oauth_signature_method="HMAC-SHA1",oauth_timestamp="1291689733",
oauth_token="QB%2FfqbXTpFB1GQ%3D%3D",
oauth_verifier="G8jTZ27hPKGTZJ%2B5qQOsqlKZ",
oauth_version="1.0"
HTTP/1.1 200 OK
Content-Type: application/x-www-form-urlencoded
oauth_token=dRsM%2BQcOhiQcow%3D%3D&
oauth_token_secret=eGt1Ym8163llDcjFeDpSQPM5Sys%3D&
url_name=sample&
display_name=Sample
(見やすさのために改行を挿入しています)
oauth_token_secret
の値も他人にもらさないように注意しましょう。
ここで得られた access token では、 2.1で request token 取得時に指定した scope の API のみ利用することができます。
3. はてなの OAuth 対応 API を利用する
例としてはてなの OAuth アプリケーション用 API を使用する方法を説明します。
https://n.hatena.com/applications/my.json に必要な scope は read_public
なので、上の例のように取得したアクセストークンが利用できます。
リクエスト例としては次のようになります。
GET /applications/my.json HTTP/1.1
Host: n.hatena.com
Authorization: OAuth realm="",
oauth_consumer_key="q7JnhZ3Hk8a%2FlQ%3D%3D",
oauth_nonce="e3fcb9046a7b67a2f135",
oauth_signature="gUXzVjtGaYBC%2BIguh2cf56Id%2BdY%3D",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1291692652",
oauth_token="dRsM%2BQcOhiQcow%3D%3D",
oauth_version="1.0"
サンプルコード
Perl 版
フレームワークとして Mojolicious::Lite、OAuth ライブラリとして OAuth::Lite を利用したサンプルコードです。
下のコードを保存して (oauth_consumer.pl
とします)、YOUR_CONSUMER_KEY
, YOUR_CONSUMER_SECRET
となっている部分を自分の consumer_key, consumer_secret で置き換えます。
$ perl oauth_consumer.pl daemon
... で起動してから http://localhost:3000/ に Web ブラウザでアクセスして下さい。
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Mojolicious::Lite;
use OAuth::Lite::Consumer;
use OAuth::Lite::Token;
use JSON;
my $consumer_key = 'YOUR_CONSUMER_KEY';
my $consumer_secret = 'YOUR_CONSUMER_SECRET';
my $consumer = OAuth::Lite::Consumer->new(
consumer_key => $consumer_key,
consumer_secret => $consumer_secret,
site => q{https://www.hatena.com},
request_token_path => q{/oauth/initiate},
access_token_path => q{/oauth/token},
authorize_path => q{https://www.hatena.ne.jp/oauth/authorize},
);
get '/' => sub {
my $self = shift;
$self->stash(access_token => $self->session('access_token') || '');
} => 'root';
# リクエストトークン取得から認証用URLにリダイレクトするためのアクション
get '/oauth' => sub {
my $self = shift;
$self->stash(consumer => $consumer);
# リクエストトークンの取得
my $request_token = $consumer->get_request_token(
callback_url => q{http://localhost:3000/callback},
scope => 'read_public',
) or die $consumer->errstr;
# セッションへリクエストトークンを保存しておく
$self->session(request_token => $request_token->as_encoded);
# 認証用URLにリダイレクトする
$self->redirect_to( $consumer->url_to_authorize(
token => $request_token,
) );
};
# 認証からコールバックされ、アクセストークンを取得するためのアクション
get '/callback' => sub {
my $self = shift;
$self->stash(consumer => $consumer);
my $verifier = $self->param('oauth_verifier');
my $request_token = OAuth::Lite::Token->from_encoded($self->session('request_token'));
# リクエストトークンとverifierなどを用いてアクセストークンを取得
my $access_token = $consumer->get_access_token(
token => $request_token,
verifier => $verifier,
) or die $consumer->errstr;
$self->session(request_token => undef);
# アクセストークンをセッションに記録しておく
$self->session(access_token => $access_token->as_encoded);
$self->redirect_to('/');
} => 'callback';
# アクセストークンを利用して、OAuthに対応したAPIを利用するためのアクション
get '/hello' => sub {
my $self = shift;
$self->stash(consumer => $consumer);
my $access_token = OAuth::Lite::Token->from_encoded($self->session('access_token')) or return;
# access_tokenなどを使ってAPIにアクセスする
my $res = $consumer->request(
method => 'GET',
url => 'http://n.hatena.com/applications/my.json',
token => $access_token,
params => {},
) or die $consumer->errstr;
my $data = decode_json($res->decoded_content || $res->content);
$self->stash(user_data => $data);
} => 'hello';
app->start;
__DATA__
@@ root.html.ep
<a href="/oauth">はてなOAuth認証をする</a>
<br />
<% if ($access_token) { %>
<a href="/hello">Hello API</a>
<% } %>
@@ callback.html.ep
% my $token = $self->stash('token');
<%= $token->token %></br>
<%= $token->secret %>
@@ hello.html.ep
url_name : <%= $user_data->{url_name} %> </br>
display_name : <%= $user_data->{display_name} %>
@@ exception.html.ep
REQUEST ERROR: <%= $consumer->errstr %> </br>
WWW-Authenticate: <%= $consumer->oauth_res && $consumer->oauth_res->header('www-authenticate') %>
Ruby 版
フレームワークとして Sinatra を、OAuth ライブラリとして OAuth を利用したサンプルプログラムです。
下のコードを保存して (oauth_consumer.rb
とします)、YOUR_CONSUMER_KEY
, YOUR_CONSUMER_SECRET
となっている部分を自分の consumer_key, consumer_secret で置き換えます。
$ ruby oauth_consumer.rb
... で起動してから http://localhost:4567 に Web ブラウザでアクセスして下さい。
require 'rubygems'
require 'sinatra'
require 'oauth'
require 'erb'
require 'json'
set :sessions, true
enable :sessions
before do
@consumer = OAuth::Consumer.new(
'YOUR_CONSUMER_KEY',
'YOUR_CONSUMER_SECRET',
:site => '',
:request_token_path => 'https://www.hatena.com/oauth/initiate',
:access_token_path => 'https://www.hatena.com/oauth/token',
:authorize_path => 'https://www.hatena.ne.jp/oauth/authorize')
end
get '/' do
erb :index
end
# リクエストトークン取得から認証用URLにリダイレクトするためのアクション
get '/oauth' do
# リクエストトークンの取得
request_token = @consumer.get_request_token(
{ :oauth_callback => 'http://localhost:4567/oauth_callback' },
:scope => 'read_public,write_public')
# セッションへリクエストトークンを保存しておく
session[:request_token] = request_token.token
session[:request_token_secret] = request_token.secret
# 認証用URLにリダイレクトする
redirect request_token.authorize_url
end
# 認証からコールバックされ、アクセストークンを取得するためのアクション
get '/oauth_callback' do
request_token = OAuth::RequestToken.new(
@consumer,
session[:request_token],
session[:request_token_secret])
# リクエストトークンとverifierを用いてアクセストークンを取得
access_token = request_token.get_access_token(
{},
:oauth_verifier => params[:oauth_verifier])
session[:request_token] = nil
session[:request_token_secret] = nil
# アクセストークンをセッションに記録しておく
session[:access_token] = access_token.token
session[:access_token_secret] = access_token.secret
erb :oauth_callback, :locals => { :access_token => access_token }
end
# アクセストークンを利用して、OAuthに対応したAPIを利用するためのアクション
get '/hello' do
access_token = OAuth::AccessToken.new(
@consumer,
session[:access_token],
session[:access_token_secret])
# access_tokenなどを使ってAPIにアクセスする
response = access_token.request(:get, 'http://n.hatena.com/applications/my.json')
if response
data = JSON.parse(response.body)
else
data = ""
end
erb :hello, :locals => { :data => data }
end
__END__
@@ index
<p><a href="/oauth">Hatena</a></p>
<% if session[:access_token] && session[:access_token_secret] %>
<a href="/hello">hello oauth api.</a>
<% end %>
@@ oauth_callback
<p>success getting access_token.</p>
<p>your access token is below.</p>
<dl>
<dt>access_token</dt>
<dd><%= access_token.params[:oauth_token] %></dd>
<dt>access_token_secret</dt>
<dd><%= access_token.params[:oauth_token_secret] %></dd>
</dl>
<a href="/">back to top</a>
@@ hello
<p>hello oauth!</p>
<dl>
<dt>url_name</dd>
<dd><%= data["url_name"] %></dd>
<dt>display_name</dt>
<dd><%= data["display_name"] %></dd>
</dl>
関連ドキュメント
- OAuth については、次の Web サイトが参考になります (はてな外のサイトです)
- はてな OAuth scope 一覧
- OAuth 対応 API 一覧
変更履歴
- 2010年12月13日 公開
- 2010年12月29日 サンプルコード Ruby版を修正
- 2012年10月24日 サンプルコード Perl版を修正