はてなサービスにおけるWSSE認証
本ドキュメントに関する注意事項
本ドキュメントは、はてなサービスの各種 Web API における WSSE 認証について説明するものです。
WSSE認証
はてなブログ、はてなフォトライフ、はてなブックマークなどのAPIではWSSE認証が利用できます。WSSE認証の詳細に関しては http://www.xml.com/pub/a/2003/12/17/dive.html (英語) を参照してください。ここではWSSE認証についての必要事項を簡単に解説します。
WSSE認証はHTTPのX-WSSEヘッダを用いて認証用文字列を送信する認証手段です。WSSE認証用文字列にはユーザー名とAPIキーが含まれます。このとき、APIキーはSHA1アルゴリズムによって暗号化されたダイジェストとして送信されるため、HTTP基本認証などに比べてセキュアな認証が可能です。
送信するX-WSSEヘッダのサンプルは以下のようになります。
X-WSSE: UsernameToken Username="hatena", PasswordDigest="ZCNaK2jrXr4+zsCaYK/YLUxImZU=", Nonce="Uh95NQlviNpJQR1MmML+zq6pFxE=", Created="2005-01-18T03:20:15Z"
Username
はてなID
Nonce
HTTPリクエスト毎に生成したセキュリティ・トークン
Created
Nonceが作成された日時をISO-8601表記で記述したもの
PasswordDigest
Nonce, Created, API キーを文字列連結しSHA1アルゴリズムでダイジェスト化して生成されたオクテット列を、Base64エンコードした文字列。APIキーは投稿メールアドレスの"@"や"+"以前の文字列になります。はてなブログの管理画面でも確認できます。
はてなアカウントのパスワードによるWSSE認証は2014年3月5日をもって廃止されました。今後はAPIキーによるWSSE認証をご利用ください。
Perl によるWSSE認証の実装
WSSE認証をPerlで実装する場合は、例えば以下のようになります。
#!/usr/local/bin/perl
use strict;
use warnings;
use DateTime;
use Digest::SHA1 qw (sha1);
use HTTP::Request;
use MIME::Base64 qw (encode_base64);
use LWP::UserAgent;
my $username = shift or die "need username\n";
my $api_key = shift or die "need API key\n";
my $nonce = sha1(sha1(time() . {} . rand() . $$));
my $now = DateTime->now->iso8601 . 'Z';
my $digest = encode_base64(sha1($nonce . $now . $api_key), '');
my $credentials =
sprintf(qq(UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"),
$username, $digest, encode_base64($nonce, ''), $now);
my $req = HTTP::Request->new(GET => 'http://f.hatena.ne.jp/atom');
$req->header( Accept => 'application/x.atom+xml, application/xml, text/xml, */*');
$req->header( 'X-WSSE' => $credentials );
print LWP::UserAgent->new->request($req)->as_string;
X-WSSE ヘッダを作成し、はてなフォトライフAtomAPIエンドポイントの認証を通過して、ルートエンドポイントにGETすることで PostURI、EditURI を取得しています。
また、CPANモジュールのLWP::Authen::Wsse を利用すると、X-WSSEヘッダを生成するロジックを書かなくても、
my $ua = LWP::UserAgent->new;
$ua->credentials('f.hatena.ne.jp:80', '', 'username', 'api_key');
と LWP::UserAgent に命令するだけで、認証ヘッダを追加したリクエストを送信することができます。