メインコンテンツまでスキップ

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をお持ちの方は、はてな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 にユーザーをリダイレクトすることを推奨します。

PChttps://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>

関連ドキュメント

変更履歴

  • 2010年12月13日 公開
  • 2010年12月29日 サンプルコード Ruby版を修正
  • 2012年10月24日 サンプルコード Perl版を修正