QQ、微信、Fackbook等第三方登录使用OAuth2.0,随便找一些文档跟着做很快实现,没什么难度。等轮到Twitter时候,如果你也这样想,后面它就会证明你是错的!
Twitter在当前时间(2018年4月20日),用的依然是OAuth1.0,相比OAuth2.0是复杂了一点,但大概流程也差不多。不管Twitter为什么仍然使用OAuth1.0,也不争论哪个更加安全,在这只单纯说一下我踩过的坑,以及给一个本人成功请求的例子,供有需要的网友快速填坑。
网上找到很多关于Twitter第三方登录的例子,注意看了一下发布时间,已经是差不多10年前的作品,所有自己掉坑里面一度以为是参考的文档太古老了,其实他们的文章依然是正确的。想自己看Twitter官方文档,无奈是难懂的英文,大学英语4级过了也远应付不了呀。而且官方文档相对比较简单,对于刚刚接触的人来说,是真的看不懂呀。没去了解过OAuth1.0协议本身,大多工作都是快餐式网上拿来改改用,如果对OAuth1.0协议本身有了解的,应该好对付。有点啰嗦,受不了的网友可以到后面直接复制案例,修改成自己实现的Twitter账号参数测试运行。
正文:
Twitter登录难在哪里?难在HTTP请求时候带的认证头,和认证头里面的签名数据生成。这里只给第一个请求的案例,其他的需要自己动手做少少修改,相信有一个成功的例子,其它的也不成难题,其它接口请求可参考本文后面的参数文章。
1、请求URL:
//url,必需全部小写。
$url = 'https://api.twitter.com/oauth/request_token';
2、认证头里面参数:
$oauth_consumer_key = "xxxx";//根据自己Twitter账号上实际数据填写。
$oauth_nonce= time() . rand();//随机数,可自己实现不同的算法。
$oauth_signature_method="HMAC-SHA1";//固定值
$oauth_timestamp=time();//固定写法,请求时候的时间戳。
$oauth_version="1.0";//固定值
$oauth_signature="?";//签名串:较复杂,实现在后面
3、请求方法:
//请求方法,必需全部大写。
$httpMethod = 'GET';
4、$oauth_signature签名串生成:生成$oauth_signature需要两个数据就是$text和$key,下面分别说明数据获取方式
4.1、$text获取
先把第2步所有参数,剔除$oauth_signature,其它参数按参数名升序排列,务必按顺序组成一个请求串
$params = "oauth_consumer_key={$oauth_consumer_key}&oauth_nonce={$oauth_nonce}&oauth_signature_method={$oauth_signature_method}&oauth_timestamp={$oauth_timestamp}&oauth_version={$oauth_version}";
得到参数$params,联合第1步的$url和第3步的$httpMethod,分别用urlencode()编码后,按格式连接起来。
格式:$text = urlencode($httpMethod) . '&' . urlencode($url) . '&' . urlencode($params)
4.2、$key获取
去Twitter查到APP的Consumer Secret (API Secret)值,在这个值后面再连一个 '&' ,便成了所需要的$key。
4.3、得到$text和$key,便可以用HMAC-SHA1算法生成签名,具体算法可自己百度,后面示例中也有一种算法可参考,生成签名后还需要使用urlencode()编码后方可使用。即$oauth_signature = urlencode(HMAC-SHA1($text, $key));
5、把第4步得来的$oauth_signature值,填充到第2步的$oauth_signature参数中。把第2步填充好的完整参数,按以下格式组成认证头:
$httpHeader = [
'Authorization: OAuth ' .
'oauth_consumer_key='.$oauth_consumer_key .
',oauth_nonce='.$oauth_nonce .
',oauth_signature_method='.$oauth_signature_method .
',oauth_timestamp='.$oauth_timestamp .
',oauth_version='.$oauth_version .
',oauth_signature='.$oauth_signature
];
6、请求Twitter接口:
使用第1步的$url、第3步的请求方法和第6步的请求认证头信息,便可以发起curl模拟请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch);
if (false === $ret) {
$ret = curl_errno($ch);
}
curl_close($ch);
echo $ret;
最后、贴上自己案例,网友根据自己Twitter账号实际情况修改一下配置即可测试运行
$blocksize)
{
$key = pack('H*', $hashfunc($key));
}
$key = str_pad($key,$blocksize,chr(0x00));
$ipad = str_repeat(chr(0x36),$blocksize);
$opad = str_repeat(chr(0x5c),$blocksize);
$hmac = pack(
'H*',$hashfunc(
($key^$opad).pack(
'H*',$hashfunc(
($key^$ipad).$str
)
)
)
);
$signature = base64_encode($hmac);
}
return $signature;
}
$time = time();
$oauth_consumer_key = $consumerKey;
$oauth_nonce=$time . rand();
$oauth_signature_method="HMAC-SHA1";
$oauth_timestamp=$time;
$oauth_version="1.0";
//请求方法,必需全部大写。
$httpMethod = 'GET';
//url,必需全部小写。
$url = 'https://api.twitter.com/oauth/request_token';
//参数,此次请求中的除了oauth_signature以外的所有参数按照字母顺序升序排列,如果参数名相同,那么按照参数值的字母顺序升序排列。
$params = "oauth_consumer_key={$oauth_consumer_key}&oauth_nonce={$oauth_nonce}&oauth_signature_method={$oauth_signature_method}&oauth_timestamp={$oauth_timestamp}&oauth_version={$oauth_version}";
//签名串(text)的构成:HttpMethod&url&参数。(一定是先各自urlencode后再用‘&’相连起来)
$signature_text = urlencode($httpMethod) . '&' . urlencode($url) . '&' . urlencode($params);
echo $signature_text . '';
//oauth_consumer_secret&oauth_token_secret
$key = $consumerSecret . '&';
$oauth_signature = get_signature($signature_text, $key);
echo $oauth_signature . '
';
$oauth_signature = urlencode($oauth_signature);
echo $oauth_signature . '
';
$httpHeader = [
'Authorization: OAuth ' .
'oauth_consumer_key='.$oauth_consumer_key .
',oauth_nonce='.$oauth_nonce .
',oauth_signature_method='.$oauth_signature_method .
',oauth_timestamp='.$oauth_timestamp .
',oauth_version='.$oauth_version .
',oauth_signature='.$oauth_signature
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$ret = curl_exec($ch);
if (false === $ret) {
$ret = curl_errno($ch);
}
curl_close($ch);
echo $ret;
参考文章:
https://blog.csdn.net/yangjian8915/article/details/11816669
https://www.cnblogs.com/JohnnyYin/p/3426045.html
http://blog.sina.com.cn/s/blog_72ef7bea0102wu37.html