基于php/ZF2支持OAuth1.0与OAuth2.0的第三方Oauth登录

阅读:453 2019-03-19 14:39:42 来源:开源中国

evaoauth是一个统一接口设计,兼容oauth1.0与oauth2.0规范的phpoauth登录模块,目前支持超过20个主流网站的oauth登录,包括:

国外

facebookoauth2

twitteroauth1

googleoauth2

githuboauth2

msnliveoauth2

flickroauth1

linkedinoauth1

yahoooauth1

dropboxoauth1

foursquareoauth2

disqusoauth2

国内

豆瓣doubanoauth1

豆瓣doubanoauth2

微博weibooauth2

人人网renrenoauth2

腾讯qqtencentoauth2

开心网kaixinoauth2

百度baiduoauth2

360qihoooauth2

网易微博neteaseoauth2

搜狐微博sohuoauth1

天涯tianyaoauth1

evaoauth统一接口规范,上面的任何一个第三方网站,在使用evaoauth时的代码与流程都是完全一致的,也可以很简单的扩展并加入新的第三方网站。

最终可以用20行左右代码实现以上所有支持网站的完整oauth登录授权。

推荐在项目中使用composer进行一键安装。

请编辑composer.json,加入

"require":{"allovince/evaoauth":"dev-master"},

然后运行

phpcomposer.pharinstall

即可。

evaoauth要求php版本必须高于5.3.3,并主要依赖以下几个zf2模块:

zendoauth

zendsession储存token信息,也可以自己扩展storagestorageinterface实现其他存储方式

zendjson

在同目录下会自动创建vendor目录并下载所有的依赖,在你的项目中,只需要包含自动生成的vendor/autoload.php即可。

或者请访问evaoauth的github项目主页。

参考之前的zf2在windows下的环境搭建,假设我们的php.exe目录在d:xamppphp,那么首先将php目录加入windows环境变量。

cdd:xamppphpphp-r"eval('?>'.file_get_contents('https://getcomposer.org/installer'));"

同目录下编辑文件composer.bat,内容为

@echooffsetcomposerscript=composer.pharphp"%~dp0%composerscript%"%*

运行

composer-v

检查composer安装是否成功。

进入evaoauth目录下运行:

phpd:xamppphpcomposer.pharinstall

实现oauth登录必须先在相应的第三方网站上申请应用并获得的consumerkey与consumersecret,每个网站可能叫法不太一样,以豆瓣为例:

访问豆瓣开发者,我的应用->创建新应用。创建完毕后

豆瓣应用的apikey对应evaoauth的consumerkey

豆瓣应用的secret对应evaoauth的consumersecret

假设我们将evaoauth文件夹命名为oauth并可以用http://localhost/oauth/访问,同时已经安装好了所有的依赖。我们以豆瓣的oauth2.0为例(因为豆瓣没有限制callbackurl的域,非常方便测试),用几十行代码构建一个完整的oauth登录:

首先编写一个文件request.php,内容如下:

require_once'./vendor/autoload.php';useevaoauthserviceasoauthservice;$oauth=newoauthservice();$oauth->setoptions(array('callbackurl'=>'http://localhost/evaoauth/examples/access.php','consumerkey'=>'xxx','consumersecret'=>'yyy',));$oauth->initadapter('douban','oauth2');$requesttoken=$oauth->getadapter()->getrequesttoken();$oauth->getstorage()->saverequesttoken($requesttoken);$requesttokenurl=$oauth->getadapter()->getrequesttokenurl();header("location:$requesttokenurl");

将consumerkey和consumersecret替换为在豆瓣申请应用的apikey与secret,然后访问

http://localhost/evaoauth/examples/request.php

不出意外的话会被引导向豆瓣进行授权。

这一步中,我们取得了一个requesttoken,然后将其暂存在session里。然后被跳转往第三方网站进行授权。

虽然requesttoken只存在于oauth1.0规范,但是为了兼容两个规范,即便是oauth2.0中,evaoauth也会构建一个虚拟的requesttoken。

授权后会被带往我们指定的链接callbackurl。

继续编写另一个文件access.php

require_once'./vendor/autoload.php';useevaoauthserviceasoauthservice;$oauth=newoauthservice();$oauth->setoptions(array('callbackurl'=>'http://localhost/evaoauth/examples/access.php','consumerkey'=>'xxx','consumersecret'=>'yyy',));$oauth->initadapter('douban','oauth2');$requesttoken=$oauth->getstorage()->getrequesttoken();$accesstoken=$oauth->getadapter()->getaccesstoken($_get,$requesttoken);$accesstokenarray=$oauth->getadapter()->accesstokentoarray($accesstoken);$oauth->getstorage()->saveaccesstoken($accesstokenarray);$oauth->getstorage()->clearrequesttoken();print_r($accesstokenarray);

在这一步中,从session中取出上一步获得的requesttoken,配合callbackurl中携带的参数,最终会换取一个授权的accesstoken。上例中我们会看到最终获得的accesstoken信息:

array([adapterkey]=>douban[token]=>tokenxxxxxxx[expiretime]=>2012-12-0615:20:38[refreshtoken]=>refreshtokenxxxxxx[version]=>oauth2[remoteuserid]=>1291360)

取得accesstoken后,我们可以根据需求将其存入数据库或以其他方式存放。如果需要携带accesstoken访问api也很简单,比如使用上例中的$accesstokenarray:

$oauth=newoauthservice();$oauth->setoptions(array('consumerkey'=>'xxx','consumersecret'=>'yyy',));$oauth->initbyaccesstoken($accesstokenarray);$adapter=$oauth->getadapter();$client=$adapter->gethttpclient();$client->seturi('https://api.douban.com/v2/user/~me');$response=$client->send();print_r($response->getbody());

evaoauth最终返回的accesstoken格式是统一的,但是由于第三方应用规定的差别,并不是所有的参数都一定存在:

adapterkey(required):第三方网站名,全小写

token(required):accesstoken

tokensecret:accesstokensecret,仅在oauth1.0中存在

version(required):值为oauth1/oauth2

refreshtoken:refreshtoken

expiretime:accesstoken过期时间,为utc时间

remoteuserid(required):当前用户在第三方网站的userid

remoteusername:当前用户在第三方网站的username

remoteextra:取得accesstoken时的其他附加信息,如果有则为一个json字符串

每次用户的oauth登录,只需要判定adapterkey/version/remoteuserid三个值完全一致时,即可认为是同一用户。

很多第三方应用内需要将测试用的域名加入白名单。

yahoooauth必须在apppermissions栏选择并设定至少一项权限,否则会出现oauth_problem=consumer_key_rejected错误

由于zendhttp新版本存在bug,可能会引起

fatalerror:calltoamemberfunctionconnect()onanon-objectinzend/http/client.php

这样的报错,目前修复的方法是强制使用旧版本的zendhttp,项目composer.json中指定:

"allovince/evaoauth":"dev-master","zendframework/zend-http":"2.2.3",

重新运行composer即可

相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服