简单的 Twitter Oauth 授权每次都要求提供凭据
我正在使用此处的教程制作一个简单的基于 Twitter 的登录/注册系统。每次让用户登录时,我都会获得 oauth_token 以及 oauth 令牌秘密。但是,即使用户已经登录,系统也会要求他再次登录。我只是想知道如何检查用户是否已经登录?
我是否需要在会话中存储 oauth_token 和 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];
}
}
I am making a simple twitter based login/signup system using the tutorial here. I get the oauth_token as well as oauth token secret every time I get the user to login. However, even when the user is already logged in, he is being asked to login again. I just wanted to know how do I check if the user is already logged in?
Do I need to store the oauth_token and oauth token secret in session? If I do store these in a session, how do i authenticate if they are valid?
The library used has something like this:
<?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];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
(c) https://dev.twitter.com/docs/auth/ Sign-in-with-twitter
因此,找到他们的库(或您的代码)对
/authorize
端点执行请求的位置,并将其替换为/authenticate
关于令牌:只要您收到了用户令牌 - 将其存储在一些持久的存储(数据库、文件等),因为令牌是永久的(它们将一直有效,直到用户没有手动撤销它们)。
(c) https://dev.twitter.com/docs/auth/sign-in-with-twitter
So find where their library (or your code) performs request to
/authorize
endpoint and replace it with/authenticate
About tokens: as long as you've received user tokens - store it in some persistent storage (database, file, etc) since that tokens are permanent (they will be valid until user haven't revoked them manually).
为应用程序 OAuth 设置启用“使用 Twitter 登录”选项
Enable option "Sign in with Twitter" for application OAuth Settings