【学无止境】 基于ThinkPHP的OAuth2.0实现 ----OAuth2.0 个人学习笔记 Two
来源:互联网 发布:mmd动作数据导入maya 编辑:程序博客网 时间:2024/05/21 23:32
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指的是appid isset($_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_token if (!$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"}
0 0
- 【学无止境】 基于ThinkPHP的OAuth2.0实现 ----OAuth2.0 个人学习笔记 Two
- 【学无止境】基于ThinkPHP的OAuth2.0实现 ------ OAuth2.0个人学习笔记 One
- OAuth2.0 学习笔记
- OAuth2.0学习笔记
- 基于oauth2.0的第三方登录实现
- 【PHP】基于ThinkPHP框架搭建OAuth2.0服务
- 【PHP】基于ThinkPHP框架搭建OAuth2.0服务
- 【PHP】基于ThinkPHP框架搭建OAuth2.0服务
- 一大坨GoogleAPI的学习笔记之三(基于oAuth2.0的domain-wide authentication)
- OAuth2.0实现过程
- OAuth2.0协议学习
- OAuth2.0学习
- 基于OAUTH2.0的授权操作
- 学习 OAuth2.0 笔记( 一 )
- 【OAuth2.0学习笔记一】原理介绍
- 一大坨GoogleAPI的学习笔记之一(oAuth2.0)
- OAuth2.0 的使用
- OAuth2.0 的理解
- 经典搜索-nefuoj1205-和为k
- struts2中Date日期转换失败
- 设计模式之状态模式
- JAVA——java中类的public class与class的区别详解
- linux下solr6.4通过虚拟机连接mysql数据库导入数据查询
- 【学无止境】 基于ThinkPHP的OAuth2.0实现 ----OAuth2.0 个人学习笔记 Two
- 1011. A+B和C (15) PAT
- FileWriter字符流写入缓存限制
- javascript中函数的5个高级技巧
- 再简单的页面都找不到了+jsp收action中的传值报错
- Java的native方法
- Linux命令(8)——rz命令与sz命令
- JAVA反射-getGenericSuperclass()用法
- yii操作数据库