RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
RECOMMEND
SELECTED ENTRIES
RECENT COMMENTS
RECENT TRACKBACK
CATEGORIES
ARCHIVES
MOBILE
qrcode
LINKS
PROFILE
OTHERS

12
--
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
--
>>
<<
--

bose999's memo

<< PHPで簡単なテンプレートエンジン作ってみる | main | ドトール社に学ぶ最新 OSS 活用事例 >>
OAuthを理解するためにtwitterで遊んでみた
0
    OAuthを理解するためにライブラリは使わずにやり取りを
    ざっと実装してみたのでメモ。

    処理の流れは下記。
    動作しているものはここ

    index.htmlから認証を要求するためのrequest.phpへ遷移

    request.phpからサービスプロバイダーのtwitterへ
    リクエストトークンを送り仮のユーザのトークンと
    ユーザの秘密鍵を保持する。

    サービスプロバイダの認証用ページに遷移してユーザに許可を促す

    callback.phpヘ遷移する。

    callback.phpのGET値を取得する。

    twitterからGET値で渡されたトークンと保持してるトークンを比較して
    不正アクセスではないかを確認する。

    twitterからアクセストークンを取得する。

    アクセストークンを表示する。
    【index.html】

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>bose999's twitter OAuth Test</title>
    </head>
    <body>
    bose999's twitter OAuth Test<br />
    <a href="./request.php">OAuth 認証へ</a>
    </body>
    </html>


    【request.php】

    <?php
    include_once('OAuthLogin.php');

    //twitterページへ遷移する為、SESSIONでの値渡し。
    session_start();

    //OAuthLoginクラスをインスタンス化
    $oAuthLogin = new OAuthLogin();

    //プログラムごとで割り当てられた値をセットする
    $oAuthLogin->consumerKey "xxxx";
    $oAuthLogin->consumerSecret ="xxxx";
    $oAuthLogin->callbackURL ="http://techie.jp/oauth/callback.php";

    //レスポンス処理を行う
    $oAuthLogin->getRequestTokenResponse();

    //セッションでトークンチェック等を行うので情報が入っている
    //OAuthLoginクラスをセッションに保存
    $_SESSION['oAuthLogin'] = $oAuthLogin;

    //アクセストークンをもらうページに遷移
    $oAuthLogin->getAccessToken($requestTokens);



    【callback.php】

    <?php
    include_once('OAuthLogin.php');
    session_start();

    //セッションからOAuthLoginを復元
    $oAuthLogin $_SESSION['oAuthLogin'];

    //GET値を渡す
    $oAuthLogin->checkAccessToken(
        array(
    "oauth_verifier" => $_GET['oauth_verifier'],
        
    "oauth_token"=>$_GET['oauth_token'])
        );

    //アクセストークンを取得する
    $oauthTokens $oAuthLogin->getAccessTokenResponse();

    //アクセストークンの内容を侮ヲする
    ?>
    <html>
    <title>bose999's twitter OAuth Test</title>
    <body>
    bose999's OAuth 認証完了
    <br />
    screen_name:
    <?php echo $oauthTokens['screen_name'?>
    <br />
    oauth_token:
    <?php echo $oauthTokens['oauth_token'?>
    <br />
    oauth_token_secret:
    <?php echo $oauthTokens['oauth_token_secret'?>
    <br />
    </body>
    </html>


    【OAuthLogin.php】
    <?php
    class OAuthLogin{
        const 
    REQUEST_TOKEN_URL "http://twitter.com/oauth/request_token";
        const 
    ACCESS_TOKEN_URL "http://twitter.com/oauth/access_token";
        const 
    AUTHORIZE_URL "http://twitter.com/oauth/authorize";

        var 
    $oauthToken null;
        var 
    $oauthTokenSecret null;
        var 
    $oauthVerifier null;

        
    //アプリによって書き換える事
        
    var $consumerKey null;
        var 
    $consumerSecret null;
        var 
    $callbackURL null;

        function 
    __set($name$value){
            
    $this->values[$name] = $value;
        }

        function 
    __get($name){
            return 
    $this->values[$name];
        }

        
    // サービスにコンシュマーとしてリクエストトークンを送り  仮のユーザのトークンとユーザの秘密鍵を保持する
        
    public function getRequestTokenResponse(){

            
    $oauthParameter $this->makeRequestParameter();
            
    $url self::REQUEST_TOKEN_URL."?".$oauthParameter;

            
    $requestTokens $this->getResponse($url);

            
    $this->oauthToken $requestTokens['oauth_token'];
            
    $this->oauthTokenSecret $requestTokens['oauth_token_secret'];
        }

        
    // サービスプロバイダの認証用URIを侮ヲしてユーザに許可を促す
        
    public function getAccessToken(){
            
    header("Location:".self::AUTHORIZE_URL."?oauth_token={$this->oauthToken}");
        }

        
    // 保持してあるトークンを比較して違う場合は正常なアクセスではないと判定
        
    public function checkAccessToken($values){

            
    $this->oauthVerifier $values['oauth_verifier'];

            
    //callback値とsession値の比較
            
    if($this->oauthToken != $values['oauth_token']){
                
    //値が違うので不正 
                
    die("Failed oauth token");
            }
        }

        
    // コールバックを受けて再度アクセストークンの取得
        
    public function getAccessTokenResponse(){

            
    $oauthParameter $this->makeAccessParameter();
            
    $url self::ACCESS_TOKEN_URL."?".$oauthParameter;

            return 
    $this->getResponse($url);
        }

        
    // twitterに対しての汎用HTTPコール処理
        
    private function getResponse($url){
            
    $curl curl_init();
            
    curl_setopt($curlCURLOPT_URL$url);
            
    curl_setopt($curlCURLOPT_RETURNTRANSFER1);
            
    $responseString curl_exec($curl);
            if (!
    $responseString) {
                die(
    "Failed request token");
            } else if (
    $responseString == "Failed to validate oauth signature and token") {
                die(
    "Failed to validate oauth signature and token");
            }
            
    curl_close($curl);
            
    $responses split("&"$responseString);
            
    $oauthTokens = array();
            foreach (
    $responses as $response) {
                list(
    $key$value) = split("="$response);
                
    $values[$key] = $value;
            }
            return 
    $values;
        }

        
    // リクエストトークン用パラーメタ作成
        
    private function makeRequestParameter(){

            
    $oauthParameters = array('oauth_consumer_key' => $this->consumerKey,
                            
    'oauth_signature_method' => 'HMAC-SHA1',
                           
    'oauth_timestamp' => time(),
                            
    'oauth_nonce' => md5(microtime() . mt_rand()),
                            
    'oauth_version' => '1.0',
                            
    'oauth_callback' => $this->callbackURL
            
    );

            return 
    $this->makeParameterString($oauthParameters,self::REQUEST_TOKEN_URL,"");
        }

        
    // アクセストークン要求用パラメータ作成
        
    private function makeAccessParameter(){
            
    $oauthParameters = array('oauth_consumer_key' => $this->consumerKey,
                            
    'oauth_signature_method' => 'HMAC-SHA1',
                            
    'oauth_token' => $this->oauthToken,
                            
    'oauth_verifier' => $this->oauthVerifier,
                            
    'oauth_timestamp' => time(),
                            
    'oauth_signature' => $this->oauthTokenSecret,
                            
    'oauth_nonce' => md5(microtime() . mt_rand()),
                            
    'oauth_version' => '1.0'
                            
    );
                            return 
    $this->makeParameterString($oauthParameters,self::ACCESS_TOKEN_URL,$oauthVerifier);
        }

        
    // トークン生成共通処理
        
    private function makeParameterString($oauthParameters,$url,$secret){

            
    $oauthParametersSort array_map(array($this,"encodeURLRFC3986"), $oauthParameters);
            
    uksort($oauthParametersSort'strnatcmp');
            
    $oauthParametersSortString $this->makeKeyValueANDString($oauthParametersSort);
            
    $data"GET&".$this->encodeURLRFC3986($url)."&".$this->encodeURLRFC3986($oauthParametersSortString);
            
    $key $this->encodeURLRFC3986($this->consumerSecret)."&".$this->encodeURLRFC3986($secret);
            
    $oauthSignature=base64_encodehash_hmac('sha1'$data$keytrue));
            
    $oauthParameters['oauth_signature']=$oauthSignature;

            
    $oauthParameter $this->makeKeyValueANDString(array_map(array($this,"encodeURLRFC3986"), $oauthParameters));

            return 
    $oauthParameter;
        }

        
    // マップをkey=value&key=valueの形式に変換
        
    private function makeKeyValueANDString($values){
            
    $keyValueString '';
            foreach (
    $values as $key => $value) {
                if(
    $keyValueString != ''){
                    
    $keyValueString $keyValueString.'&';
                }
                
    $keyValueString $keyValueString.$key.'='.$value;
            }
            return 
    $keyValueString;
        }

        
    // URLエンコードRFC3986対応版
        
    private function encodeURLRFC3986($input){
            return 
    str_replace('+',' ',str_replace('%7E''~'rawurlencode($input)));
        }
    }


    | PHP | 12:25 | comments(0) | trackbacks(0) | - | - |









    http://bose.techie.jp/trackback/843685