2011-09-28 87 views
2

我正在使用教程here製作一個簡單的基於Twitter的登錄/註冊系統。我每次獲得用戶登錄時都會獲得oauth_token以及oauth令牌密鑰。但是,即使用戶已經登錄,他仍被要求再次登錄。我只是想知道如何檢查用戶是否已經登錄?簡單的Twitter Oauth授權每次都要求憑據

我是否需要在會話中存儲oauth_token和oauth令牌密鑰?如果我將它們存儲在會話中,我如何驗證它們是否有效?

使用的庫有這樣的事情:在Twitter的實現OAuth的規範

<?php 
session_start(); 
class EpiOAuth 
{ 
    public $version = '1.0'; 

    protected $requestTokenUrl; 
    protected $accessTokenUrl; 
    protected $authorizeUrl; 
    protected $consumerKey; 
    protected $consumerSecret; 
    protected $token; 
    protected $tokenSecret; 
    protected $signatureMethod; 

    public function getAccessToken() 
    { 
    $resp = $this->httpRequest('GET', $this->accessTokenUrl); 
    return new EpiOAuthResponse($resp); 
    } 

    public function getAuthorizationUrl() 
    { 
    $retval = "{$this->authorizeUrl}?"; 
    $token = $this->getRequestToken(); 
    return $this->authorizeUrl . '?oauth_token=' . $token->oauth_token; 
    } 

    public function getRequestToken() 
    { 
    $resp = $this->httpRequest('GET', $this->requestTokenUrl); 
    return new EpiOAuthResponse($resp); 
    } 

    public function httpRequest($method = null, $url = null, $params = null) 
    { 
    if(empty($method) || empty($url)) 
     return false; 

    if(empty($params['oauth_signature'])) 
     $params = $this->prepareParameters($method, $url, $params); 

    switch($method) 
    { 
     case 'GET': 
     return $this->httpGet($url, $params); 
     break; 
     case 'POST': 
     return $this->httpPost($url, $params); 
     break; 
    } 
    } 

    public function setToken($token = null, $secret = null) 
    { 
    $params = func_get_args(); 
    $this->token = $token; 
    $this->tokenSecret = $secret; 
    } 

    public function encode($string) 
    { 
    return rawurlencode(utf8_encode($string)); 
    } 

    protected function addOAuthHeaders(&$ch, $url, $oauthHeaders) 
    { 
    $_h = array('Expect:'); 
    $urlParts = parse_url($url); 
    $oauth = 'Authorization: OAuth realm="' . $urlParts['path'] . '",'; 
    foreach($oauthHeaders as $name => $value) 
    { 
     $oauth .= "{$name}=\"{$value}\","; 
    } 
    $_h[] = substr($oauth, 0, -1); 

    curl_setopt($ch, CURLOPT_HTTPHEADER, $_h); 
    } 

    protected function generateNonce() 
    { 
    if(isset($this->nonce)) // for unit testing 
     return $this->nonce; 

    return md5(uniqid(rand(), true)); 
    } 

    protected function generateSignature($method = null, $url = null, $params = null) 
    { 
    if(empty($method) || empty($url)) 
     return false; 


    // concatenating 
    $concatenatedParams = ''; 
    foreach($params as $k => $v) 
    { 
     $v = $this->encode($v); 
     $concatenatedParams .= "{$k}={$v}&"; 
    } 
    $concatenatedParams = $this->encode(substr($concatenatedParams, 0, -1)); 

    // normalize url 
    $normalizedUrl = $this->encode($this->normalizeUrl($url)); 
    $method = $this->encode($method); // don't need this but why not? 

    $signatureBaseString = "{$method}&{$normalizedUrl}&{$concatenatedParams}"; 
    return $this->signString($signatureBaseString); 
    } 

    protected function httpGet($url, $params = null) 
    { 
    if(count($params['request']) > 0) 
    { 
     $url .= '?'; 
     foreach($params['request'] as $k => $v) 
     { 
     $url .= "{$k}={$v}&"; 
     } 
     $url = substr($url, 0, -1); 
    } 
    $ch = curl_init($url); 
    $this->addOAuthHeaders($ch, $url, $params['oauth']); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    $resp = $this->curl->addCurl($ch); 

    return $resp; 
    } 

    protected function httpPost($url, $params = null) 
    { 
    $ch = curl_init($url); 
    $this->addOAuthHeaders($ch, $url, $params['oauth']); 
    curl_setopt($ch, CURLOPT_POST, 1); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params['request'])); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    $resp = $this->curl->addCurl($ch); 
    return $resp; 
    } 

    protected function normalizeUrl($url = null) 
    { 
    $urlParts = parse_url($url); 
    $scheme = strtolower($urlParts['scheme']); 
    $host = strtolower($urlParts['host']); 
    $port = intval($urlParts['port']); 

    $retval = "{$scheme}://{$host}"; 
    if($port > 0 && ($scheme === 'http' && $port !== 80) || ($scheme === 'https' && $port !== 443)) 
    { 
     $retval .= ":{$port}"; 
    } 
    $retval .= $urlParts['path']; 
    if(!empty($urlParts['query'])) 
    { 
     $retval .= "?{$urlParts['query']}"; 
    } 

    return $retval; 
    } 

    protected function prepareParameters($method = null, $url = null, $params = null) 
    { 
    if(empty($method) || empty($url)) 
     return false; 

    $oauth['oauth_consumer_key'] = $this->consumerKey; 
    $oauth['oauth_token'] = $this->token; 
    $oauth['oauth_nonce'] = $this->generateNonce(); 
    $oauth['oauth_timestamp'] = !isset($this->timestamp) ? time() : $this->timestamp; // for unit test 
    $oauth['oauth_signature_method'] = $this->signatureMethod; 
    $oauth['oauth_version'] = $this->version; 

    // encoding 
    array_walk($oauth, array($this, 'encode')); 
    if(is_array($params)) 
     array_walk($params, array($this, 'encode')); 
    $encodedParams = array_merge($oauth, (array)$params); 

    // sorting 
    ksort($encodedParams); 

    // signing 
    $oauth['oauth_signature'] = $this->encode($this->generateSignature($method, $url, $encodedParams)); 
    return array('request' => $params, 'oauth' => $oauth); 
    } 

    protected function signString($string = null) 
    { 
    $retval = false; 
    switch($this->signatureMethod) 
    { 
     case 'HMAC-SHA1': 
     $key = $this->encode($this->consumerSecret) . '&' . $this->encode($this->tokenSecret); 
     $retval = base64_encode(hash_hmac('sha1', $string, $key, true)); 
     break; 
    } 

    return $retval; 
    } 

    public function __construct($consumerKey, $consumerSecret, $signatureMethod='HMAC-SHA1') 
    { 
    $this->consumerKey = $consumerKey; 
    $this->consumerSecret = $consumerSecret; 
    $this->signatureMethod = $signatureMethod; 
    $this->curl = EpiCurl::getInstance(); 
    } 
} 

class EpiOAuthResponse 
{ 
    private $__resp; 

    public function __construct($resp) 
    { 
    $this->__resp = $resp; 
    } 

    public function __get($name) 
    { 
    if($this->__resp->code < 200 || $this->__resp->code > 299) 
     return false; 

    parse_str($this->__resp->data, $result); 
    foreach($result as $k => $v) 
    { 
     $this->$k = $v; 
    } 

    return $result[$name]; 
    } 
} 
+0

[Rü使用一個新的窗口或同一頁面上嘰嘰喳喳的東西? – diEcho

+0

同一頁。有關係嗎? –

回答

4

正常流程決定了應用程序發送的請求令牌的OAuth /授權。要利用「使用Twitter登錄」,應用程序應將oauth_token參數中收到的請求令牌發送到oauth/authenticate。

(C)https://dev.twitter.com/docs/auth/sign-in-with-twitter

所以尋找到他們的圖書館(或者代碼)執行請求/authorize端點與/authenticate

關於令牌替換:只要你已經收到用戶令牌 - 將其存儲在某些永久性存儲(數據庫,文件等)中,因爲該令牌爲永久(它們將在用戶尚未手動撤銷它們之前有效)。

+0

我剛剛發佈了我使用的庫的代碼 –

+2

@ Yahoo-Me:那麼? Stackoverflow - 是一個開發人員社區。我很抱歉,但我不會爲你做你的工作。我給了你一個答案**爲什麼會發生。現在修復*你的*代碼。 – zerkms

+0

@雅虎我看看右側的建議問題,你應該能夠得到它的排序。 – Arc

4

啓用選項「登錄與Twitter」爲應用程序的OAuth設置

+0

這個爲我工作。謝謝! – iamtankist