【学无止境】 基于ThinkPHP的OAuth2.0实现 ----OAuth2.0 个人学习笔记 Two
ThinkPHP 结合 OAuth2.0
准备工作
第一我们得准备好OAuth2.0的源码包,下载地址点这里。
我们将下载好的源码包放在thinkphp的
vendor
文件夹下面。这里注意只要src
文件夹下的OAuth2
放入vendor
即可。如下图:
新建模块
oauth2.0
然后将其路由等信息配置完毕。
开始工作
- 首先还是在配置文件中把OAuth的PDO数据库配置完成
//OAuth数据库配置'OAUTH_DB_HOST'=>'xxxxx.com','OAUTH_DB_NAME'=>'xxx','OAUTH_DB_USER'=>'xxx','OAUTH_DB_PWD'=>'xxxxxxxx',
- 新建
IndexController
作为本次学习的主控制器,注意本控制器请继承RestController
(thinkphp封装)
class IndexController extends RestController
- 新建
authorize
公共方法来处理用户的授权请求和换取code的工作
public function authorize(){//默认response_type为code$_GET['response_type'] = isset($_GET['response_type'])?$_GET['response_type']:'code';//数据表字段为client_id指的是appidisset($_GET['appid']) && $_GET['client_id'] = $_GET['appid'];$oauth = new OAuthModel();$request = \OAuth2\Request::createFromGlobals();$response = new \OAuth2\Response();if (!$oauth->server()->validateAuthorizeRequest($request, $response)) {$response->send();exit();}//用户同意授权后$is_authorized = ($_POST['authorized'] == 'yes');//生成code(绑定你的业务user_id)$oauth->server()->handleAuthorizeRequest($request, $response, $is_authorized,$user_id);if ($is_authorized) {$code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40);//返回第三方服务//所带参数state,code,$parses = $_REQUEST;$back_parses = array('state'=>$parses['state'],'code'=>$code,);//跳转回第三方服务器if(!$parses['redirect_url']) $this->err("redirect_url丢失!");redirect( base64_decode($parses['redirect_url']) . '?' . http_build_query($back_parses));}else{$parses = $_GET;$back_parses = array('state'=>$parses['state'],);//跳转回第三方服务器redirect( urldecode($parses['redirect_url']) . '?' . http_build_query($back_parses) );}}
- 获取到了code之后我们需要拿着这个code去换token,新建公共方法
token
完成以下工作
public function token(){//默认grant_type为authorization_code(授权码模式)$_POST['grant_type'] = isset($_POST['grant_type'])?$_POST['grant_type']:'authorization_code';$oauth = new OAuthModel();$oauth->server()->handleTokenRequest(\OAuth2\Request::createFromGlobals())->send();
}
- 拿到了这个token后我们就要校验这个token是否是正确的token,这个时候回到我们自己的项目目录下新建
CheckTokenController
控制器。
class CheckTokenController extends BaseController
{protected function _initialize(){parent::_initialize();$oauth = new OAuthModel();if(!$_REQUEST['access_token']){$this->err("未找到access_token,请确认已传入access_token");}//验证access_tokenif (!$oauth->server()->verifyResourceRequest(\OAuth2\Request::createFromGlobals())) {$oauth->server()->getResponse()->send();exit();}//删除不必要的GET参数unset($_GET['m']);unset($_GET['c']);unset($_GET['a']);unset($_GET['access_token']);}
}
所有的项目资源控制器必须继承该控制器!!!
- 最后一步,回到自己的资源控制器里面编写自己的逻辑代码
class UserController extends CheckAccessTokenController
{public function user_info(){switch ($this->_method){case 'get':$model = new UserModel();$this->suc("用户信息获取成功",$model->user_info($this->user_id));break;case 'post'://数据更新:使用动态验证,验证数据合法性同时验证数据是更新还是插入//TODO:当数据为更新时一定注意须包含主键id,否则将自动判断为插入数据//动态验证,逻辑代码}}}
测试方法举例
当我们完成整个编写流程后我们需要如何去测试呢? 在这里我也提供一个测试的方法与大家共享
- 将用户导向授权层获取
code
public function user(){$url = "http://xxxxxx/resource/user/access_token/". $this->get_oauth_token() ;$this->test($url);}
- 检查是否有
token
public function get_oauth_token(){if($code = $_GET['code']){//TODO::验证返回的state 防止CSRF攻击$code = $_GET['code'];$res = $this->code2oauthtoken($code);if($res->access_token){return $res->access_token;}else{echo "无效的code";exit();}}else{$this->redirect_oauth();}}
protected function redirect_oauth($url){$url = $url?:get_url();//TODO::使用state参数防止CSRF攻击 当用户跳转到授权服务器前,使用session储存state,当用户跳转回来时,比对state,以此判断用户身份是否改变redirect('http://xxxxxxx/oauth2.0/authorize/appid/testclient/state/xyz/redirect_url/'.base64_encode($url));}
- 成功拿回
code
拿code
换取token
public function code2oauthtoken($code){$url = 'xxxxxx/oauth2.0/token';//$url =ROOT_URL . U('Home/Index/token');$method = 'post';$param = array('grant_type'=>'authorization_code','code'=>$code,);$header = array('Authorization: Basic ' .base64_encode(self::APPID . ':' . self::APPSECRET),);$res = http_request($url,$method,$param,$header);$res = json_decode($res);return $res;}
- 最终获取资源层资源
{
"error": 0,
"message": "数据拿出成功",
"data": "RE_zjw"
}
【学无止境】 基于ThinkPHP的OAuth2.0实现 ----OAuth2.0 个人学习笔记 Two相关推荐
- ASP.NET Core分布式项目实战(oauth2 + oidc 实现 client部分)--学习笔记
任务16:oauth2 + oidc 实现 client部分 实现 client 之前启动一下上一节的 server,启动之前需要清除一些代码 注释 Program 的 MigrateDbContex ...
- ASP.NET Core分布式项目实战(oauth2 + oidc 实现 server部分)--学习笔记
任务15:oauth2 + oidc 实现 server部分 基于之前快速入门的项目(MvcCookieAuthSample): ASP.NET Core快速入门(第5章:认证与授权)--学习笔记 A ...
- Echarts3.0入门基础与实战(学习笔记)
1.浏览器画图原理简介 2.Echarts库简介 3.Echarts简单使用 4.Echarts组件使用 5.Echarts高级图例介绍 6.扩展知识 1.浏览器画图原理简介 canvas 基于像素, ...
- 阿里云天池 Python训练营Task4: Python数据分析:从0完成一个数据分析实战 学习笔记
本学习笔记为阿里云天池龙珠计划Python训练营的学习内容,学习链接为:https://tianchi.aliyun.com/specials/promotion/aicamppython?spm=5 ...
- 基于百度英伟达EasyDL公开课的学习笔记
本文是基于智东西公开课<零算法基础的百度EasyDL定制化图像识别揭秘>整理的学习笔记 本文非广告,标注单纯是出于尊重智东西和EasyDL的知识产权 如若涉及侵权,请联系本人 作者:李皮皮 ...
- 基于C#的中望CAD二次开发学习笔记(1)环境测试
目录 前言 一.ZRXSDK的安装使用 二.创建项目 三.编写环境测试代码 四.在ZWCAD中测试 参考资料 总结 前言 作为一个设计院搬砖人,和各种CAD打交道是必不可少的.当然,其中最为正统的是A ...
- 引用:基于C#的中望CAD二次开发学习笔记
目录 前言 一.ZRXSDK的安装使用 二.创建项目 三.编写环境测试代码 四.在ZWCAD中测试 参考资料 总结 前言 作为一个设计院搬砖人,和各种CAD打交道是必不可少的.当然,其中最为正统的是A ...
- ASP.NET Core基于K8S的微服务电商案例实践--学习笔记
摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...
- 基于《狂神说Java》JUC并发编程--学习笔记
前言: 本笔记仅做学习与复习使用,不存在刻意抄袭. -------------------------------------------------------------------------- ...
- java基于聚类的离群点检测_挑子学习笔记:基于两步聚类的离群点检测
转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/anomaly_detection.html 本文主要针对IBM SPSS Modeler 18.0中离群点检 ...
最新文章
- 应用基于资产的开发到 SOA 的服务中1
- 定制简单的Linux系统
- [面试专题]Web缓存详解
- boost::tokenizer模块相关的测试程序
- C++智能指针 shared_ptr、weak_ptr
- shell (7)if 表达式
- 系统烧写方法(MfgTool烧写工具)
- C++ throw:抛出自己的异常
- BIC/ImageGP稳定性问题
- C++中内存泄漏的检测
- Oracle中单双引号
- Nginx 常用配置,避坑指南!
- MapGIS目录的设置
- 共享OrCAD9.2pSpice9.2+multisim下载地址
- MATLAB GUI中的handles
- 心态对了一切都对了 -- Entropy 熵
- 华为手机linux终端,华为云IoT如何让“哑”终端进化为智能终端?看完这场直播你就明白了...
- 九、springboot+ idea + gradle使用jib打docker镜像
- fastadmin框架里基于x-editable实现的表格无刷新行内编辑功能的插件的‘datetime‘时间类型无法使用的解决方法
- 充电宝买哪种比较好?评价最好的充电宝推荐