OAuthについて(OpenIDとは違うのだよ)

Category : PHP < ウェブ開発

Tags : php OAuth API

OAuth

OpenIDが、あなたは本人ですか?ねぇほんと?ねぇ?的な身元証明の技術であるのに対して、OAuthはこの人に合い鍵渡していい?ねぇ?ほんとにいいの?的な私財へのアクセス許可の技術です。

現在、Twitterの他にもYahooやGoogleのAPIもOAuth認証に対応しています。FlickrもOAuthのベースになってるような認証だった気がするけど、今はどうなんでしょうね。

とりあえずベーシック認証よりは、よっぽどセキュアというわけですが、詳しいメリットや成り立ちなどは、下の参考URLでもご覧くださいまし。

参考:APIアクセス権を委譲するプロトコル、OAuthを知る − @IT

そのプロセス

コンシューマー登録
アパートの管理人(サービスプロバイダ ex.Twitter)に、合い鍵収集業者(コンシューマー)として登録し、業者ID ( コンシューマーキーコンシューマーシークレット ) を得ます。
リクエストトークンの請求
アパートの住人(ユーザー ex.Twitterユーザー)に、合い鍵くれとリクエストを送ります。その際、業者IDをユーザーに渡して、OKなら業者IDを管理人に渡してくれ、と頼みます。
ユーザーの認否
ユーザーは管理人のとこに行って、この業者に合い鍵を渡すかどうかを判断します。(Twitterとの連携サービスとかをやると、良く出てくるアレです。許可・不許可の。)
リクエストトークンの発行
ユーザーがOKを出してくれると、合い鍵業者は、管理人に合い鍵を請求するための委任状(リクエストトークン)をもらえます。
アクセストークンの入手
委任状を手に入れた合い鍵業者は、それを携えて管理人に、そのユーザーの合い鍵(アクセストークン)をもらいに行って、それを受け取ります。
合い鍵が変わったら?
合い鍵はたまに変わってしまうかもしれません。そのとき、合い鍵業者は委任状と前の鍵を持って、もう一度管理人に会いに行きます。委任状が今でも有効なら、新しい合い鍵を受け取れます。すでに無効なら、それは住人が、あなたとの縁を切ったということです。

逆にわかりづらい?

抽象化したら逆に分かりづらい気がする。そうでもないか?まあ、そんな感じでトカゲのしっぽを切れる程度の便利認証でござる。一晩だけの関係とかでもいいわけですよ。合い鍵業者とか訳の分からないことを言わずに、夜這い業者と訳した方が良かったか。

前エントリーで述べたような、HTTPリクエストの実装よりは、よっぽどハマりポイントはありません。仕様に従って作れば一通り問題ありませんでした。OAuthで重要なのは、その意義(使い所)とプロセスを理解することです。

RFC3986の形式でちゃんとエンコードしないとダメとか、そういうのはありますが、コンシューマー側を作る分には、そこまで大変ではありません。サービスプロバイダー側を実装するのは結構面倒くさそうな...。



HTTPリクエストするためのクラス書いてみた

Category : PHP < ウェブ開発

Tags : HTTP php

HTTPリクエスト再び

Twitter API用のライブラリがどうとか言いながら、全然公開してませんな。

スピンアウト品による、HTTPリクエストについてメモしとくです。この後にOAuthかな。そしてTwitter, Flickr, Google, YahooあたりのAPIと遊ぶ方法とか。一通り試した後なので、暇を見つけながら、内容をまとめて自分メモ的にブログ書くつもり。a-blog cmsと連携したTwitter BOTぐらいはちゃんと作って公開すっか。

APIを叩く用に

<?php
$http = new SimpleHttp();

$http->get('http://havelog.ayumusato.com');

$res = $http->header;
$body = $http->body;

if ( !($http->error) ) {
     return true;
} else {
     return false;
}
?>

GET!POST!で適当にリクエスト投げれて、レスポンスヘッダーもレスポンスボディも、一通り取ってこれるようにしたかったのです。API相手しか考えてないので、POSTメソッドもクエリーのやり取りしか考えられてません。

file_get_contentsとかだとレスポンスコード200以外のときのレスポンスボディを端折りやがるので、ソケット接続から始めてリクエストを書き込んで受け取って、と地味な作業を繰り返してます。地味ですけど、HTTPの仕様の勉強になります。裏でこういうやり取りされてたんですね。

ハードウェアやソフトウェアの深淵を見るには、文系の自分には叶いません。でも、たまーに少し深いところを垣間見ると、なんとなく、してやったりという気分になれます。ああ現金。

覚え書きリスト

  • リクエスト時の改行コードはCR+LFで鉄板くさい
  • 末尾の改行コードが足りないとシカトされることすらある
  • ステータスコード204と304はレスポンスボディがない(仕様的に)
  • HTTP1.1のchunkedデータは、送ってきたり送ってこなかったりする
  • chunked受け取りたくなかったら1.0としてリクエスト
  • phpのparse_url関数はステキ(regex書き終わった頃に教えてもらった)
  • httpsはssl://に変換して、portも合わせて変える


HTTPって大変だね

Category : PHP < ウェブ開発

Tags : HTTP php

HTTPリクエスト

class TinyHttp
{
    public $header;
    public $body;
    public $error;
    public function __construct($url, $context = null)
    {
        if ( !empty($context) ) {
            $this->body   = @file_get_contents($url, false, $context);
        } else {
            $this->body   = @file_get_contents($url);
        }
        $this->header   = $http_response_header;
        $this->error    = !((bool) $this->body);
    }
    public function getStatusCode()
    {
        if ( preg_match('@^\s?HTTP\/([0-9].[0-9x])\s+([0-9]{3})\s+([0-9a-zA-z\s]*)$@', $this->header[0], $match) )
        {
        $status = array(
                        'version'   => $match[1],
                        'code'      => $match[2],
                        'status'    => $match[3],
                        );
        }
        return !empty($status) ? $status : false;
    }
}
//contextはなくてもいい。
$http = new TinyHttp($request, stream_context_create($context));
//ヘッダー
print_r $http->header;
if ( $http->error ) {
    //しっぱい
} else {
    //どれどれボディを見せてもらおうか
    print_r $http->body;
}

こんなん書いてみたわけさ。API宛てに手軽にリクエスト撃ちたかったので。

したら、不都合ありありで苦戦した次第。

PHPの組み込み関数は200 OK以外のレスポンスボディを取ってこない

※レスポンスボディは、HTTPでどっかのサーバーをぺちっと叩いて、返ってきたモノのメイン部分。前半分のサーバー同士のやり取りに使われる取り決められた情報は、レスポンスヘッダーらしい。

file_get_contentsとかstream_get_contentsのファイルやらストリームの関数は、正常にリクエストできないとWarnning噴くわボディは取ってこないわ潔すぎる感じ。

Twitter APIの場合、401 Not Authorizedとか、400 Bad Requestが返ってきたときにボディまで読まないと真の理由が分からなかったりする。(ボディ読んでも適当なことのほうが多いけど)

下記の情報によると、PHP5.3からはコンテキストにignore_errorsを混ぜるといいらしい。でも5.3って、仕事では、いまだにお目に掛かったことない罠。あと、既存の関数共も、正確には2xxなときに取ってくるみたい。200限定ではないらしい。

参考:HTTP ストリーム ignore_errors オプション in PHP 5.3 - 親方、空から覚え書きが!

$http_response_headerはよい子

何らかのHTTP的な動作の直後に、このhttp_response_headerという変数にレスポンスヘッダーが格納されるみたい。配列型で。$はついてるけど、定数的な動作?

上のコードでも、コレのおかげでレスポンスヘッダーだけは何となく取得できるので良い感じ。

file_get_contentsでもPOSTできる

やれば出来る子ですねー。上のコードも、file_get_contentsに適当に依存してるので、context混ぜればPOSTします。

参考:file_get_contentsでPOSTデータ送信 - PHPはやれば出来る子

車輪のナントカ?

というような発見と悩みを抱えながら、ソケット接続からHTTPリクエストして、レスポンスヘッダーもボディもちゃんと取ってくる、API叩く君を書いてました。いまだに、gzipの処理とか、chunkedなデータの扱いとかが納得いかないできばえ。もうちょっと頑張ります。