OAuth1.0実践のfoursquareクライアントはご飯に同期しますか?

4945 ワード

前回は「OAuth2.0実践のfoursquareクライアントログイン」と言っていましたが、今回はやはりOAuth 1に戻ります.0.
やはり私が書いたfoursquareのwebクライアントプログラムです.その中にファンNoに同期する機能がついていて、もともとはBasicAuthを使っていたが、ファンNoは今年の元旦からBasicAuthを閉鎖し、OAuth 1に全面的に変更すると発表した.0.そこで私はまた締め切りの数日前にこのプログラムを書き直さなければなりません.前回のように完全に書き直さなくても、すぐに書き直さなければなりません.ただしその中でもOAuth 1.0の署名部分はいくつかの基礎関数に影響し、いくつかの場所を変更し、いくつかの悪い味を出しました.どうせphpを使うのはquick and dirtyのためだから、再構築なんておっくうだから、使えばいい.
同様に、ここではプログラムの他の部分も議論せず、食事に同期するかどうかの部分だけを話します.
標準のOAuth 1.0ログインプロセスは次のとおりです.
1、サービス提供者にクライアントアプリケーションを登録し、一対のconsumerを取得する.keyとconsumer_secret;
2、プロバイダを呼び出すoauth request_tokenは一時的なtokenを取得します.
3、この一時tokenとコールバックアドレスで提供者のauthorizeページに転向し、ユーザーはこのページで授権するかどうかを決定する.
4、ユーザーの授権後、提供者はコールバックアドレスに転向し、verifierコードを提供する.
5、このverifierコードと一時token呼び出しプロバイダのoauth access_tokenが正式なアクセスを取得token;
6、accessを使うtokenはプロバイダのAPIを呼び出す.
以上のすべての呼び出し要求にconsumerを添付する必要があります.key/secret、デジタル署名.
明らかにOAuth 2より0は複雑ですが、この技術は成熟しており、既存のライブラリがたくさんあります.私の仮想ホストはまだPHP 4しかサポートしていないので、PHP 4をサポートできるライブラリを使用しています:lib_oauth.php.あの流行のOAuth.phpライブラリは実は少し変えてもいいです.私も試したことがありますが、既製のものを使うのが便利だと思います.このlibに変えました.oauthです.
ちなみに、国内のこれらのサイトはAPIを提供していると言われていますが、それぞれの実現には妖蛾がいて、海外のサイトほど規範的ではありません.特に新浪と騰迅を筆頭に、網易と捜狐はやや良いが、捜狐にも問題がある、OAuth 1.0 Head方式はサポートされておらず、パラメータにもいくつかの特別な要求があります.食事の有無については、verifierコードがないとは!時間やIPなどで鑑定されたのだろう.
はい、具体的にはこの応用に行きます.私が実現しなければならない機能は2つあります.1つはログインファンNo、2つはファンNo APIを通じてメッセージを送信することです.
まず、食事の有無で公式にkey/secretを申請します.
次にfoursquareログインセクションのような方法で、ファンNoログインを実現します.
ユーザーはリンクをクリックし、プログラムはrequest_を呼び出します.tokenはご飯Noのauthorizeにリダイレクトし、ユーザーは許可を確認してからコールバックし、プログラムはaccessを呼び出す.tokenが正式なアクセスを取得token(注意:verifierはここにありません)を保存します.
最後に、ご飯否APIを呼び出す前にOAuth 1を用いる.0仕様は、要求署名を行います.
具体的なログインコードは以下の通りです.
function fanfou_login() {
 session_start();
 $GLOBALS['user']['fantype'] = 'oauth';

 if ($oauth_token = $_GET['oauth_token']) {  //         
  $response = fanfou_process(FANFOU_OAUTH.'access_token');  //      access_token,         verifier
  parse_str($response, $token);
  $GLOBALS['user']['fanpass'] = $token['oauth_token'] .'|'.$token['oauth_token_secret'];
  unset($_SESSION['oauth_request_token_secret']);
  $user = fanfou_process(FANFOU_API.'account/verify_credentials.json');  //      API           
  $GLOBALS['user']['fanuser'] = $user->id;
  _user_save_cookie(1);
  header('Location: '.BASE_URL.SF_CALLBACK.'?'.http_build_query(array('redir' => BASE_URL)));
  exit();
 } else {  //          
  $response = fanfou_process(FANFOU_OAUTH.'request_token');  //      token
  parse_str($response, $token);
  $_SESSION['oauth_request_token_secret'] = $token['oauth_token_secret'];
  $authorise_url = FANFOU_OAUTH.'authorize?oauth_token='.$token['oauth_token']."&oauth_callback=".BASE_URL.FANFOU_CALLBACK;
  header("Location: $authorise_url");  //       authorize  ,      
 }
}

アクセスを取得token以降および取得前のリクエストは、仕様に従ってconsumerに参加する必要があります.key/consumer_secretは、署名を行います(署名内容には仕様要件のすべてのフィールドが含まれていますが、この作業はoauthライブラリで処理されています).
function fan_oauth_sign(&$url, &$args) {
 require_once 'lib_oauth.php'; //     lib_oauth  
 $method = $args !== false ? 'POST' : 'GET';
 if (preg_match_all('#[?&]([^=]+)=([^&]+)#', $url, $matches, PREG_SET_ORDER)) {
  foreach ($matches as $match) {
   $args[$match[1]] = $match[2];
  }
  $url = substr($url, 0, strpos($url, '?'));
 }
 if (($oauth_token = $_GET['oauth_token']) && $_SESSION['oauth_request_token_secret']) {
  $oauth_token_secret = $_SESSION['oauth_request_token_secret'];
 } else {
  list($oauth_token, $oauth_token_secret) = explode('|', $GLOBALS['user']['fanpass']);
 }
  $keys = array(
  'oauth_key'  => OAUTH_CONSUMER_KEY,
 'oauth_secret' => OAUTH_CONSUMER_SECRET,
 'user_key' => $oauth_token,
 'user_secret' => $oauth_token_secret,
 );
 $url = oauth_sign_get($keys, $url, $args, $method);  // OAuth1.0  

 if ($method == 'POST'){
 list($url, $args) = explode('?', $url, 2);
 }else{
 $args = false;
 }
}

function fanfou_process($url, $post_data = false) {
 fan_oauth_sign($url, $post_data);
 $result = api_process($url, $post_data);
 $response = $result['response'];
 $response_info = $result['response_info'];
    //       json    ,  ……
}

このコードはOAuth 2よりも見える.0はそれほど複雑ではありませんが、oauthライブラリを使用した場合にこのような簡略化があります.OAuth 2を用いる.0であれば他のライブラリに依存することなく実現でき,また簡単である.
クライアントコード全体がGoogle Codeにダウンロードされます.