博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CI环境下开发Oauth2.0开放平台
阅读量:7241 次
发布时间:2019-06-29

本文共 7102 字,大约阅读时间需要 23 分钟。

Oauth2.0

代码已push到github欢迎star:

0x01.About

最近在搭建Oauth2.0第三方接入开放平台,主要是使用Github开源项目服务模块和CodeIgniter结合。

一般来说做开放平台主要包括:Oauth2.0认证平台、Resource资源API平台、Open开发者注册平台,以及API说明等。

Oauth2.0测试平台已经搭建好,请访问


0x02.About Oauth2.0

OAuth 2.0授权前,第三方应用必须到平台上进行注册,注册过程中可能需要填写的内容有:应用类型,授权成功回调地址,以及其他平台需要的资料(应用名称、网址、介绍、LOGO图片等)。

OAuth 2.0标准主要围绕三类应用:Web应用、基于客户端的应用、原生应用。

应用在Open开发者平台注册完成会得到一个应用client_id和一个client_secret,一般叫App Key,密钥叫App Secret,这两样东西作用跟用户名密码是一样的。

中提到的授权方式有四种:授权码(Authorization Code)、隐式授权(Implicit Grant)、用户口令(Resource Owner Password Credentials)、应用口令(Client Credentials)。

这四种方式最终的目的都是要获得Access Token,然后通过请求Resource服务器获取资源。


0x03.Grant_type

说说每种授权方式使用到的地方,或授权的方式。

Authorization Code

Authorization Code

授权码方式在很多地方都有用到,微博登陆,微信登陆等都是。

认证过程主要是跳转到Oauth2.0平台,认证后跳转回第三方应用平台,并通过callback的url中携带code、state、token_type等信息,然后第三方平台通过code获取到access_token,进而调用开放API获取到资源。

第三方请求过程必须附带,response_type(回调类型:code,token),client_id(开发者app key),redirect_uri(回调链接),state(防止csrf,authorization认证跳转后原样返回)。

例如::8085/oauth2/authorize/index?redirect_uri=

测试例子:

第一步:跳转到Oauth2.0服务器:

认证过程中会请求scope权限表,用户可以拒绝相应权限。

跳转到Oauth2.0服务器

第二步:用户确认请求的权限,回调得到code:

用户确认请求的权限

第三步:第三方平台通过code得到access_token,然后通过API调用Resource服务器资源。

这个过程需要发送client_idclient_secret(App Secret),grant_type('authorization_code'),coderedirect_uri给oauth2服务器获取access_token

例如:

Implicit Grant

隐式授权流程(Implicit Grant)其实就是Authorization Code的一个简化版本,不是回调code,而是直接回调access_token给第三方开发者,response_type变为token,其他和Authorization Code一样。

例如:

跳转后就得到了,如下链接:

Client Credentials

应用授权(Client Credentials)主要用于第三方应用直接获取一些公开的数据,不需要用户跳转认证,也不需要获取用户的openid,因为都是一些公共的资源。

Client Credentials

我的请求数据为:{client_id: "testclient", client_secret: "testpass", grant_type: "client_credentials", scope: "userinfo cloud file node"}

Oauth2给我的回调数据:{"access_token":"417206d0e162d743338c04da9f8eb72f99daff6b","expires_in":3600,"token_type":"Bearer","scope":"userinfo cloud file node"}

可以看到有了access_token,然后我就可以用access_token去找Resource服务器要资源了,这里限定了scope权限表,表的权限在open平台注册的时候就确定下来了。

Resource Owner Password Credentials

用户口令(Resource Owner Password Credentials)适合内部应用调用使用,比如公司有两个平台,A和B,那么我就可以在Oauth2下通过Password Credentials模式实现A应用与B应用之间通信,还可以开放内部接口。

Client Credentials

请求的数据格式是:

`{grant_type: "password
username:"user", password: "pass",client_id: ""testclient", client_secret: "testpass", scope: "userinfo cloud file node}`

回调数据比Client Credentials多了一个refresh_token:

`{"access_token":"8a478275f8d2d5ac767f94ef0684a1fc2883eb24",

"expires_in":3600,
"token_type":"Bearer",
"scope":"userinfo cloud file node",
"refresh_token":"69a5e7b995ed4376bd6dd58380bfe09b51137dcb"}`

那么当access_token过期后,就可以通过refresh_token再次激活一个新的access_token,黑魔法,自己给自己开后门。

激活请求发送的数据为:

`{grant_type: "refresh_token",
username:"user", password: "pass", client_id: ""testclient", client_secret: "testpass", scope: "userinfo cloud file node}`

返回还是一个新的access_token数据。


0x04.CodeIgniter与Oauth2.0

四种授权方式都说过了,那么就开始搭建基于CodeIgniter的Oauth2.0平台了。

基础环境搭建

1.下载CI框架:$wget https://codeload.github.com/bcit-ci/CodeIgniter/zip/3.0.0

2.解压 $unzip CodeIgniter-3.0.0.zip

3.进入library目录 $cd CodeIgniter-3.0.0/application/libraries

4.获取oauth2-php-server: git clone https://github.com/bshaffer/oauth2-server-php && mv -f oauth2-server-php oauth2

5.通过composer安装 oauth2-server-php :cd oauth2 && composer install

如果国内composer安装慢的话,我打了一个包,可以再这里下载到:

Oauth2.0数据库

好了,ci和oauth2都处理好了,接下来导入下数据库的sql文件。

oauth2.0平台支持多种数据库,可以在oauth2/src/Oauth2/Storage/里面看到,有mongodb、mysql、redis等。

这里就选简单的mysql吧,数据库主要包含oauth_access_tokens、oauth_authorization_codes、oauth_clients、oauth_jwt、oauth_refresh_tokens、oauth_scopes、oauth_users几个表。

oauth_users是Password Credentials认证的时候用的表,oauth_scopes存放权限表,oauth_refresh_tokens是Password Credentials认证的时候的refresh_token表,oauth_clients存放开发者注册的信息表。

sql文件可以在这里下载:

Server服务

接下来在CodeIgniter-3.0.0/application/libraries/oauth2里面新建一个server.php

用于对oauth2内调用与对外ci服务的接口。

创建一个Authorization Code服务

class Server{  function __construct(){    OAuth2\Autoloader::register();    $this->storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:dbname=oauth;host=localhost', 'username' => '', 'password' => ''));    $this->server = new OAuth2\Server($this->storage, array('allow_implicit' => true));    $this->request = OAuth2\Request::createFromGlobals();    $this->response = new OAuth2\Response();  }  public function authorize($is_authorized){    $this->server->addGrantType(new OAuth2\GrantType\AuthorizationCode($this->storage));    $this->server->handleAuthorizeRequest($this->request, $this->response, $is_authorized);    if ($is_authorized) {      $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40);      header("Location: ".$response->getHttpHeader('Location'));    }    $response->send();  }}

创建一个Password Credentials服务

class Server{  function __construct(){    OAuth2\Autoloader::register();    $this->storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:dbname=oauth;host=localhost', 'username' => '', 'password' => ''));    $this->server = new OAuth2\Server($this->storage, array('allow_implicit' => true));    $this->request = OAuth2\Request::createFromGlobals();    $this->response = new OAuth2\Response();  }  public function password_credentials(){    $users = array("user" => array("password" => 'pass', 'first_name' => 'homeway', 'last_name' => 'yao'));    $storage = new OAuth2\Storage\Memory(array('user_credentials' => $users));//user是认证的账户,在表oauth_users中    $this->server->addGrantType(new OAuth2\GrantType\UserCredentials($storage));    $this->server->handleTokenRequest($this->request)->send();  }}

创建一个Client Credentials服务

class Server{  function __construct(){    OAuth2\Autoloader::register();    $this->storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:dbname=oauth;host=localhost', 'username' => '', 'password' => ''));    $this->server = new OAuth2\Server($this->storage, array('allow_implicit' => true));    $this->request = OAuth2\Request::createFromGlobals();    $this->response = new OAuth2\Response();  }  public function client_credentials(){    $this->server->addGrantType(new OAuth2\GrantType\ClientCredentials($this->storage, array("allow_credentials_in_request_body" => true)));    $this->server->handleTokenRequest($this->request)->send();  }}

创建一个refresh_token服务

class Server{  function __construct(){    OAuth2\Autoloader::register();    $this->storage = new OAuth2\Storage\Pdo(array('dsn' => 'mysql:dbname=oauth;host=localhost', 'username' => '', 'password' => ''));    $this->server = new OAuth2\Server($this->storage, array('allow_implicit' => true));    $this->request = OAuth2\Request::createFromGlobals();    $this->response = new OAuth2\Response();  }  public function refresh_token(){    $this->server->addGrantType(new OAuth2\GrantType\RefreshToken($this->storage, array(         "always_issue_new_refresh_token" => true,      "unset_refresh_token_after_use" => true,      "refresh_token_lifetime" => 2419200,    )));    $this->server->handleTokenRequest($this->request)->send();  }}

0x04.About Package

篇幅太大了,我觉定,把代码打包下来,好了。^.().^

下面是打包好的测试平台你也可以通过来进入测试平台。

平台web访问路径为:/oauth/test//oauth2/RefreshToken,/oauth2/resource,/oauth2/authorize/token,/oauth2/PasswordCredentials,/oauth2/ClientCredentials,你也可以从相应的源码中读到这些地址。

build-oauth2-under-codeigniter


参考:

1.

2.
3.
4.
5.
6.


本文出自 ,转载请注明出处:

-by小草

2015-06-29 02:04:10

你可能感兴趣的文章
Linux PAM&&PAM后门
查看>>
3 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之heartbeat的搭建
查看>>
第一百二十三节,JavaScript错误处理与调试
查看>>
WebAssembly,可以作为任何编程语言的编译目标,使应用程序可以运行在浏览器或其它代理中——浏览器里运行其他语言的程序?...
查看>>
【公告】博客数据异常已所有恢复
查看>>
JavaScript 刚開始学习的人应知的 24 条最佳实践
查看>>
java中finalkeyword
查看>>
.net core中使用Type.GetType()从字符串获取类型遇到的问题
查看>>
select选中获取索引三种写法
查看>>
词袋模型bow和词向量模型word2vec
查看>>
分享升级架构师路上的体会,兼说我为什么有挣钱紧迫感
查看>>
浏览器 HTTP 协议缓存机制详解
查看>>
understand软件使用教程(转)
查看>>
【JavaScript】 JS面向对象的模式与实践
查看>>
13.ng-value
查看>>
8天掌握EF的Code First开发系列之动手写第一个Code First应用
查看>>
【Django】 积累
查看>>
iOS App的加固保护原理
查看>>
测试左移和测试右移
查看>>
云开发初探 —— 更简便的小程序开发模式
查看>>