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') %>