unoh.github.com

PECL::oauthでxAuth

Wed Feb 24 21:19:47 -0800 2010

yamaokaです。

TwitterのBasic認証によるユーザー認証が6月に廃止されるようですね。 認証はOAuthで行ってください、とのことなのですが OAuthの認証画面を表示するためにブラウザを起動するのがふさわしくないケースや、 そもそも貧弱なブラウザでうまく利用できないケースもあります。

そうした場合の解決方法として、xAuthという仕組みがTwitterに実装されています。 詳しくは次に紹介するweb上の記事を参照してください。

認証にはユーザーの名前とパスワードを使いますが、 それを元にaccess_tokenとaccess_token_secretを取得できるので以後の認証にはパスワードが不要になるというものです。 これならBasic認証の代わりに使うことができそうですね。 勿論、OAuthを利用できるシーンではOAuthを用いた認証が望ましいのですが、 必ずしも当てはまらないケースもあるということで。

PythonやRubyを使った実装サンプルは見つかったので、 PHPのものはないかなと探してみるとありました。 ただしベトナム語タイ語なのでPHPのコードしか読めないということと、 実装コードがPHPの関数ベースなので少し使いづらそうです。

そこで普段OAuthを利用する際に使っているPECL::oauthで実装できないか試してみました。 ちなみに通常のOAuth認証を利用する場合のサンプルはリポジトリにコミットされているので参照することができます。

<?php
$consumerKey         = 'YOUR-CONSUMER-KEY';
$consumerSecret      = 'YOUR-CONSUMER-SECRET';
$userName            = 'YOUR-USER-NAME';
$password            = 'YOUR-PASSWORD';
$xAuthAccessTokenUrl = 'https://api.twitter.com/oauth/access_token';

$response = '';
$parameters = array(
    'x_auth_mode'     => 'client_auth',
    'x_auth_username' => $userName,
    'x_auth_password' => $password,
);

try {
    $oauth = new OAuth($consumerKey, $consumerSecret,
        OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
    $oauth->fetch($xAuthAccessTokenUrl, $parameters, OAUTH_HTTP_METHOD_POST);
    $response = $oauth->getLastResponse();
} catch (OAuthException $e) {
    echo "Error\n";
    exit;
}

// oauth_token=xxx&oauth_token_secret=xxx&
// user_id=xxx&screen_name=xxx&x_auth_expires=0
parse_str($response, $accessTokenInfo);

// oauth_token, oauth_token_secret, user_id, screen_name,
// x_auth_expires
var_dump($accessTokenInfo);

$accessTokenInfoの要素として「oauth_token」と「oauth_token_secret」が入っているので、 それをDBなどに保存しておくようにすれば通常のOAuth認証を用いてツイートの投稿などを行うことができるようになります。 そのまま利用して投稿するとすると、次のような感じになります。

$oAuthStatusesUpdateUrl = 'http://twitter.com/statuses/update.xml';

$response = '';
$parameters = array(
    'status' => 'YOUR-STATUS-MESSAGE',
);

$oauthToken       = $accessTokenInfo['oauth_token'];
$oauthTokenSecret = $accessTokenInfo['oauth_token_secret'];

try {
    $oauth->setToken($oauthToken, $oauthTokenSecret);
    $oauth->fetch($oAuthStatusesUpdateUrl, $parameters, OAUTH_HTTP_METHOD_POST);
    $response = $oauth->getLastResponse();
} catch (OAuthException $e) {
    echo "Error\n";
    exit;
}

var_dump($response);

仕組みとしては非常に単純なものなので、 現在Twitterの認証にBasic認証を仕方なく使っているケースでも 比較的簡単に置換ができるのではと思います。 当然、OAuthが利用できるのであれば そちらを使うのが望ましいのは言うまでもありませんが。