ThinkPHP 结合 OAuth2.0

准备工作

  1. 第一我们得准备好OAuth2.0的源码包,下载地址点这里。

  2. 我们将下载好的源码包放在thinkphp的vendor文件夹下面。这里注意只要src文件夹下的OAuth2放入vendor即可。如下图:

  3. 新建模块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));}
  • 成功拿回codecode 换取 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相关推荐

  1. ASP.NET Core分布式项目实战(oauth2 + oidc 实现 client部分)--学习笔记

    任务16:oauth2 + oidc 实现 client部分 实现 client 之前启动一下上一节的 server,启动之前需要清除一些代码 注释 Program 的 MigrateDbContex ...

  2. ASP.NET Core分布式项目实战(oauth2 + oidc 实现 server部分)--学习笔记

    任务15:oauth2 + oidc 实现 server部分 基于之前快速入门的项目(MvcCookieAuthSample): ASP.NET Core快速入门(第5章:认证与授权)--学习笔记 A ...

  3. Echarts3.0入门基础与实战(学习笔记)

    1.浏览器画图原理简介 2.Echarts库简介 3.Echarts简单使用 4.Echarts组件使用 5.Echarts高级图例介绍 6.扩展知识 1.浏览器画图原理简介 canvas 基于像素, ...

  4. 阿里云天池 Python训练营Task4: Python数据分析:从0完成一个数据分析实战 学习笔记

    本学习笔记为阿里云天池龙珠计划Python训练营的学习内容,学习链接为:https://tianchi.aliyun.com/specials/promotion/aicamppython?spm=5 ...

  5. 基于百度英伟达EasyDL公开课的学习笔记

    本文是基于智东西公开课<零算法基础的百度EasyDL定制化图像识别揭秘>整理的学习笔记 本文非广告,标注单纯是出于尊重智东西和EasyDL的知识产权 如若涉及侵权,请联系本人 作者:李皮皮 ...

  6. 基于C#的中望CAD二次开发学习笔记(1)环境测试

    目录 前言 一.ZRXSDK的安装使用 二.创建项目 三.编写环境测试代码 四.在ZWCAD中测试 参考资料 总结 前言 作为一个设计院搬砖人,和各种CAD打交道是必不可少的.当然,其中最为正统的是A ...

  7. 引用:基于C#的中望CAD二次开发学习笔记

    目录 前言 一.ZRXSDK的安装使用 二.创建项目 三.编写环境测试代码 四.在ZWCAD中测试 参考资料 总结 前言 作为一个设计院搬砖人,和各种CAD打交道是必不可少的.当然,其中最为正统的是A ...

  8. ASP.NET Core基于K8S的微服务电商案例实践--学习笔记

    摘要 一个完整的电商项目微服务的实践过程,从选型.业务设计.架构设计到开发过程管理.以及上线运维的完整过程总结与剖析. 讲师介绍 产品需求介绍 纯线上商城 线上线下一体化 跨行业 跨商业模式 从0开始 ...

  9. 基于《狂神说Java》JUC并发编程--学习笔记

    前言: 本笔记仅做学习与复习使用,不存在刻意抄袭. -------------------------------------------------------------------------- ...

  10. java基于聚类的离群点检测_挑子学习笔记:基于两步聚类的离群点检测

    转载请标明出处:http://www.cnblogs.com/tiaozistudy/p/anomaly_detection.html 本文主要针对IBM SPSS Modeler 18.0中离群点检 ...

最新文章

  1. 应用基于资产的开发到 SOA 的服务中1
  2. 定制简单的Linux系统
  3. [面试专题]Web缓存详解
  4. boost::tokenizer模块相关的测试程序
  5. C++智能指针 shared_ptr、weak_ptr
  6. shell (7)if 表达式
  7. 系统烧写方法(MfgTool烧写工具)
  8. C++ throw:抛出自己的异常
  9. BIC/ImageGP稳定性问题
  10. C++中内存泄漏的检测
  11. Oracle中单双引号
  12. Nginx 常用配置,避坑指南!
  13. MapGIS目录的设置
  14. 共享OrCAD9.2pSpice9.2+multisim下载地址
  15. MATLAB GUI中的handles
  16. 心态对了一切都对了 -- Entropy 熵
  17. 华为手机linux终端,华为云IoT如何让“哑”终端进化为智能终端?看完这场直播你就明白了...
  18. 九、springboot+ idea + gradle使用jib打docker镜像
  19. fastadmin框架里基于x-editable实现的表格无刷新行内编辑功能的插件的‘datetime‘时间类型无法使用的解决方法
  20. 充电宝买哪种比较好?评价最好的充电宝推荐

热门文章

  1. 微软笔试题 2013暑期实习笔试题目
  2. figure文本框乱码 matlab_Matlab给系统自动生成的窗体Figure1改名称
  3. android添加常驻图标到状态栏
  4. asp.net 中GridView控件实现全选及反选的功能
  5. golang中的socket
  6. mysql创建表的时候显式申明存储引擎
  7. 嵌入式系统编程软件架构主要包括哪些知识?
  8. 四轴飞行器1.1 Matlab 姿态显示
  9. Node.js的3m安装法
  10. mybaits十四:使用if和where标签构建动态sql