请大神指导一下 yii2 的yii2 oauth 2认证2 什么玩

yii2-整合PayPal SDK 待测
yii2-整合PayPal SDK 待测
发布时间: 23:06:34
编辑:www.fx114.net
本篇文章主要介绍了"yii2-整合PayPal SDK 待测",主要涉及到yii2-整合PayPal SDK 待测方面的内容,对于yii2-整合PayPal SDK 待测感兴趣的同学可以参考一下。
下载安装SDK包 install the
然后按以下步骤操作
1. Create a component to glue Paypal to Yii2
Create a components folder in your @app directory. If you are using the basic template, this is the same folder as
webroot; in the advanced template, this folder is in the app you want to enable payments in.
Create a PHP class file (CashMoney for example) with the following content
use yii\base\Component;
use PayPal\Rest\ApiContext;
use PayPal\Auth\OAuthTokenCredential;
class CashMoney extends Component {
public $client_id;
public $client_secret;
private $apiContext; // paypal's API context
// override Yii's object init()
function init() {
$this-&apiContext = new ApiContext(
new OAuthTokenCredential($this-&client_id, $this-&client_secret);
public function getContext() {
return $this-&apiContext();
This is enough to get started. You may choose to add other configurations specific to PayPal later on.
2. Register your glue component with Yii2
In your app/config/main.php (or app/config/main-local.php), include the following to register the
CashMoney component.
'components' =& [
'cm' =& [ // bad abbreviation of &CashMoney&; not sustainable long-term
'class' =& 'app/components/CashMoney', // note: this has to correspond with the newly created folder, else you'd get a ReflectionError
// Next up, we set the public parameters of the class
'clientId'
=& 'your id you can find it over your paypal develpoer account. Ypu ah to create an application',
'clientSecret' =& 'your id you can find it over your paypal develpoer account. Ypu ah to create an application',
// You may choose to include other configuration options from PayPal
// as they have specified in the documentation
Now we have our payment component registered as CashMoney, we can access it using
Yii::$app-&cm. Cool, huh?
3. Make API calls
Open the controller action in which you want to handle payments, and include the following
use PayPal\Api\CreditCard;
use PayPal\Exception\PaypalConnectionException;
class PaymentsController { // or whatever yours is called
public actionMakePayments { // or whatever yours is called
$card = new PayPalCreditCard;
$card-&setType('visa')
-&setNumber('1111')
-&setExpireMonth('06')
-&setExpireYear('2018')
-&setCvv2('782')
-&setFirstName('Richie')
-&setLastName('Richardson');
$card-&create(Yii::$app-&cm-&getContext());
// ...and for debugging purposes
echo '&pre&';
var_dump('Success scenario');
echo $card;
} catch (PayPalConnectionException) {
echo '&pre&';
var_dump('Failure scenario');
一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!
二、互相尊重,对自己的言论和行为负责。
本文标题:
本页链接:验证用户的身份的过程称为验证。它通常使用的用户名和密码来判断该用户请求。
要使用&Yii&的认证框架,需要&-
配置用户应用程序组件
实现 yii\web\IdentityInterface 接口
basic&应用程序模板带有一个内置的身份验证系统。
它使用 user 应用程序组件如下面的代码所示&-
$params = require(__DIR__ . '/params.php');
$config = [
'id' =& 'basic',
'basePath' =& dirname(__DIR__),
'bootstrap' =& ['log'],
'components' =& [
'request' =& [
// !!! insert a secret key in the following (if it is empty) - this
//is required by cookie validation
'cookieValidationKey' =& '',
'cache' =& [
'class' =& 'yii\caching\FileCache',
'user' =& [
'identityClass' =& 'app\models\User',
'enableAutoLogin' =& true,
//other components...
'db' =& require(__DIR__ . '/db.php'),
'modules' =& [
'admin' =& [
'class' =& 'app\modules\admin\Admin',
'params' =& $params,
if (YII_ENV_DEV) {
// configuration adjustments for 'dev' environment
$config['bootstrap'][] = 'debug';
$config['modules']['debug'] = [
'class' =& 'yii\debug\Module',
$config['bootstrap'][] = 'gii';
$config['modules']['gii'] = [
'class' =& 'yii\gii\Module',
在上述结构中,用户的标识类配置是&app\models\User。
identity&类必须实现&yii\web\IdentityInterface&接口中方法如下&-
findIdentity()&-&查找使用指定的用户ID的身份(identity)类的实例
findIdentityByAccessToken()&-&查找使用指定的访问令牌的身份(identity)类的实例
getId()&-返回用户ID
getAuthKey()&-&返回用于验证基于cookie登录的键
validateAuthKey()&-&实现了验证基于&cookie&登录键的逻辑
从&basic&应用程序模板的&User&模型实现了所有上述功能(models/User.php)。
用户数据被存储在&&$users&属性&-
namespace app\
class User extends \yii\base\Object implements \yii\web\IdentityInterface {
public $authK
public $accessT
private static $users = [
'100' =& [
'id' =& '100',
'username' =& 'admin',
'password' =& 'admin',
'authKey' =& 'testuserid100key',
'accessToken' =& 'user100-token',
'101' =& [
'id' =& '101',
'username' =& 'demo',
'password' =& 'demo',
'authKey' =& 'testuserid-101key',
'accessToken' =& '101-userid-token',
* @inheritdoc
public static function findIdentity($id) {
return isset(self::$users[$id]) ? new static(self::$users[$id]) :
* @inheritdoc
public static function findIdentityByAccessToken($token, $type = null) {
foreach (self::$users as $user) {
if ($user['accessToken'] === $token) {
return new static($user);
* Finds user by username
* @param string $username
* @return static|null
public static function findByUsername($username) {
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
* @inheritdoc
public function getId() {
return $this-&
* @inheritdoc
public function getAuthKey() {
return $this-&authK
* @inheritdoc
public function validateAuthKey($authKey) {
return $this-&authKey === $authK
* Validates password
* @param string $password password to validate
* @return boolean if password provided is valid for current user
public function validatePassword($password) {
return $this-&password === $
第1步&-&打开URL=&&&并使用admin的登录名和密码登录到的网站,如下图所示:
第2步&-&然后,在&SiteController&控制器中添加&actionAuth()&方法,如下图所示。
public function actionAuth(){
// the current user identity. Null if the user is not authenticated.
$identity = Yii::$app-&user-&
var_dump($identity);
// the ID of the current user. Null if the user not authenticated.
$id = Yii::$app-&user-&
var_dump($id);
// whether the current user is a guest (not authenticated)
$isGuest = Yii::$app-&user-&isG
var_dump($isGuest);
第3步&-&访问URL地址:&,将看到有关&admin&用户的详细资料:
第4步&-&要登录和注销用户,可参考使用下面的代码。
public function actionAuth() {
// whether the current user is a guest (not authenticated)
var_dump(Yii::$app-&user-&isGuest);echo '&br/&';
// find a user identity with the specified username.
// note that you may want to check the password if needed
$identity = User::findByUsername("admin");
// logs in the user
Yii::$app-&user-&login($identity);
// whether the current user is a guest (not authenticated)
var_dump(Yii::$app-&user-&isGuest);echo '&br/&';
Yii::$app-&user-&logout();
// whether the current user is a guest (not authenticated)
var_dump(Yii::$app-&user-&isGuest);
首先,如要检查用户是否登录。如果该值返回false,那么我们通过调用Yii::$app-&user-&login()登录用户,并可使用&Yii::$app-&user-&logout()&方法来注销他。
第5步&-&访问URL:&,会看到下面的输出信息:
yii\web\User&类会触发以下事件&-
EVENT_BEFORE_LOGIN&-&在&&yii\web\User::login()&方法的开始时触发
EVENT_AFTER_LOGIN&-&成功登录后触发
EVENT_BEFORE_LOGOUT&- 在&yii\web\User::logout() 方法的开始时触发
EVENT_AFTER_LOGOUT&-&成功注销后触发
本站所有代码下载:请扫描本页面底部(右侧)二维码并关注微信公众号,回复:"代码下载" 获取。
上一篇:下一篇:匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。&&& Yii 有很多 extension 可以使用,在查看了 Yii 官网上提供的与 OAuth 相关的扩展后,发现了几个 OAuth2 的客户端扩展,但是并没有找到可以作为 OAuth2 Server 的扩展。因为 Yii 是组织良好的易于扩展的框架,所以完全可以集成其它的 PHP OAuth2 Server 实现方案。在 OAuth.net/2/ 官网上,提供了几个 PHP 实现的 OAuth2 Server。这里使用第一个 OAuth2-Server-php 来作为 Yii 框架的 OAuth2 Server 扩展,需要进行一些必要的整合操作,主要是编写一个类来接受 client 访问和颁发 access_token 等。第一部分: 数据库准备&&& OAuth2-Server-php& 使用的数据库结构采用 Github 上的 oauth2-server-php README.md 提供的表结构(Schema),一共有五张表:&&& mysql&&&& +--------------------------+& & | Tables_in_oauth2 & & & & |&&& +--------------------------+&&& | oauth_access_token&&&&&& |&&& | oauth_authorization_code |&&& | oauth_client&&&&&&&&&&&& |&&& | oauth_refresh_token&&&&& |&&& | user&&&&&&&&&&&&&&&&&&&& |&&& +--------------------------+&&& 5 rows in set (0.00 sec)&&& &&& 各表的名字说明了表中存取的内容,表名可自定义,自定义位置为:OAuth2/Storage/Pdo.php 48行的 config 数组中,因为这里采用的是 mysql 数据库,所以需要修改的是 Pdo,若是采用其它的存储方案,如 Redis,则自行修改对应文件即可。注意这里的数据库名称是都是单数形式。&&& 使用以下 sql 语句创建这5个表,并添加一个测试 client:&&& ###############################&&& ### oauth2 tables&&& ###############################&&& drop table if exists `oauth_client`;&&& drop table if exists `oauth_access_token`;&&& drop table if exists `oauth_authorization_code`;&&& drop table if exists `oauth_refresh_token`;&&& drop table if exists `user`;&&& CREATE TABLE `oauth_client` (&&& `client_id` VARCHAR(80) NOT NULL, &&& `client_secret` VARCHAR(80) NOT NULL, &&& `redirect_uri` VARCHAR(2000) NOT NULL, &&& CONSTRAINT client_id_pk PRIMARY KEY (client_id)&&& );&&& CREATE TABLE `oauth_access_token` (&&& `access_token` VARCHAR(40) NOT NULL, &&& `client_id` VARCHAR(80) NOT NULL, &&& `user_id` VARCHAR(255), &&& `expires` TIMESTAMP NOT NULL, &&& `scope` VARCHAR(2000), &&& CONSTRAINT access_token_pk PRIMARY KEY (access_token)&&& );&&& CREATE TABLE `oauth_authorization_code` (&&& `authorization_code` VARCHAR(40) NOT NULL, &&& `client_id` VARCHAR(80) NOT NULL, &&& `user_id` VARCHAR(255), &&& `redirect_uri` VARCHAR(2000), &&& `expires` TIMESTAMP NOT NULL, &&& `scope` VARCHAR(2000), &&& CONSTRAINT auth_code_pk PRIMARY KEY (authorization_code)&&& );&&& CREATE TABLE `oauth_refresh_token` (&&& `refresh_token` VARCHAR(40) NOT NULL, &&& `client_id` VARCHAR(80) NOT NULL, &&& `user_id` VARCHAR(255), &&& `expires` TIMESTAMP NOT NULL, &&& `scope` VARCHAR(2000), &&& CONSTRAINT refresh_token_pk PRIMARY KEY (refresh_token)&&& );&&& -- &&& CREATE TABLE `user` (&&& `user_id` INT(11) NOT NULL AUTO_INCREMENT,&&& `username` VARCHAR(255) NOT NULL, &&& `password` VARCHAR(2000), &&& `first_name` VARCHAR(255), &&& `last_name` VARCHAR(255), &&& CONSTRAINT user_pk PRIMARY KEY (user_id)&&& );&&& -- test data&&& INSERT INTO oauth_client (client_id, client_secret, redirect_uri) &&& &&& VALUES ("testclient", "testpass", "http://fake/");&&& INSERT INTO user (username, password, first_name, last_name) &&& &&& VALUES ('rereadyou', '8551be07bab21fd411e43b78dbcc', 'bo', 'zhang');第二部分: 认证方案及实现&&& OAuth2 RFC 6749 规范提供了四种基本认证方案,以下针对这四种认证方案以及它们在本实现中的使用方式进行分别说面。第一种认证方式: Authorization Code Grant (授权码认证)&&& 授权码通过使用授权服务器做为客户端与资源所有者的中介而获得。客户端不是直接从资源所有者请求授权,而是引导资源所有者至授权服务器(由在RFC2616中定义的用户代理),授权服务器之后引导资源所有者带着授权码回到客户端。&&& 在引导资源所有者携带授权码返回客户端前,授权服务器会鉴定资源所有者身份并获得其授权。由于资源所有者只与授权服务器进行身份验证,所以资源所有者的凭据不需要与客户端分享。&&& 授权码提供了一些重要的安全益处,例如验证客户端身份的能力,以及向客户端直接的访问令牌的传输而非通过资源所有者的用户代理来传送它而潜在暴露给他人(包括资源所有者)。&&& 授权码许可类型用于获得访问令牌和刷新令牌并未机密客户端进行了优化。由于这是一个基于重定向的流程,客户端必须能够与资源所有者的用户代理(通常是Web浏览器)进行交互并能够接收来自授权服务器的传入请求(通过重定向)。& Authorization Code Grant 过程(又称为 Web Server Flow) 参见如下:&&& &+----------+&&& &| Resource |&&& &|&& Owner& |&&& &|&&&&&&&&& |&&& &+----------+&&& &&&&& ^&&& &&&&& |&&& &&&& (B)&&& &+----|-----+&&&&&&&&& Client Identifier&&&&& +---------------+&&& &| & & & & &+----(A)-- & Redirection URI ----&|&&&&&&&&&&&&&& |&&& &|& User-&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | Authorization |&&& &|& Agent & +----(B)-- User authenticates ---&|&&&& Server&&& |&&& &|&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&&&&&&&&&&& |&&& &| & & & & &+----(C)-- Authorization Code ---&|&&&&&&&&&&&&&& |&&& &+-|----|---+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&& && |&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& ^&&&&& v&&& & (A)& (C)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&& |&&& && |&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&& |&&& && ^&&& v&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&& |&&& &+---------+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&& |&&& &|&&&&&&&& |&---(D)-- Authorization Code ---------'&&&&& |&&& &|& Client |&&&&&&&&& & Redirection URI&&&&&&&&&&&&&&&&& |&&& &|&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&& &|&&&&&&&& |&---(E)----- Access Token -------------------'&&& &+---------+&&&&&& (w/ Optional Refresh Token)&&& 注:说明步骤(A)、(B)和(C)的直线因为通过用户代理而被分为两部分。&&& 图1:授权码流程&&& 在图1中所示的流程包括以下步骤:&&& (A)客户端通过向授权端点引导资源所有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。&&& (B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。&&& (C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI包括授权码和之前客户端提供的任何本地状态。&&& (D)客户端通过包含上一步中收到的授权码从授权服务器的令牌端点请求访问令牌。当发起请求时,客户端与授权服务器进行身份验证。客户端包含用于获得授权码的重定向URI来用于验证。&&& (E)授权服务器对客户端进行身份验证,验证授权代码,并确保接收的重定向URI与在步骤(C)中用于重定向客户端的URI相匹配。如果通过,授权服务器响应返回访问令牌与可选的刷新令牌。&&& 过程实现:&&& 1.&&& client app 使用 app id 获取 authorization code:&&& /oauth2/index.php?r=oauth2/authroize&response_type=code&client_id=testclient&state=xyz&&& 返回:$authcode = authorization code.&&& Tips: &&& authorization code will expired in 30s,可以修改 OAuth2/ResponseType/AuthorizationCode.php 中的 AuthorizationCode class 的构造方法配置参数来自定义 authorization_code 有效时间。&&& client_id 是之前注册在本 Server 上的应用名称,这属于客户端管理范畴。 &&& 这一步需要进行用户(资源所有者)登录 OAuth2 Server 来完成授权操作。用户登录属用户管理范畴,不属 OAuth2 Server 中应编写的功能。&&& 用户登录后可选择自己可以向 client app 开放的操作(授权)。&&& 这一步绑定过程中,从安全角度来考虑应强制用户重新输入用户名密码确认绑定,不要直接读取当前用户session进行绑定。 &&& 2. 获取 access_token:&&&&&& client app 使用 authorization code 换取 access_token&&&&&& curl -u testclient:testpass /oauth2/index.php?r=oauth2/token -d "grant_type=authorization_code&code=$authcode&&&&&& 返回:&&& &&& 成功:&&& &&& {"access_token":"aea4add5e4117bedd6e07ccc3f402",&&& &&& &"expires_in":3600,&&& &&& &"token_type":"bearer",&&& &&& &"scope":null,&&& &&& &"refresh_token":"269a623fb1852eefcf115f"&&& &&& }&&& &&& 失败:&&& &&& {"error":"invalid_grant",&&& &&& &"error_description":"Authorization code doesn't exist or is invalid for the client"&&& &&& }&&& Tip: 本步骤需要使用客户端的 client_id 和 client_secret 以及上一步获取的 authorization_code 换取 access_code.&&& &&&& access_tokne 有效期为 3600s, refresh_token 有效期为 1209600s,可以在 OAuth2/ResponseType/AccessToken.php 中的 AccessToken class 中的构造函数配置中进行修改。&&& && 第二种认证方式: Implicit (隐式认证)&&& &&& 隐式授权类型被用于获取访问令牌(它不支持发行刷新令牌),并对知道操作具体重定向URI的公共客户端进行优化。这些客户端通常在浏览器中使用诸如JavaScript的脚本语言实现。&&& 由于这是一个基于重定向的流程,客户端必须能够与资源所有者的用户代理(通常是Web浏览器)进行交互并能够接收来自授权服务器的传入请求(通过重定向)。&&& 不同于客户端分别请求授权和访问令牌的授权码许可类型,客户端收到访问令牌作为授权请求的结果。&&& 隐式许可类型不包含客户端身份验证而依赖于资源所有者在场和重定向URI的注册。因为访问令牌被编码到重定向URI中,它可能会暴露给资源所有者和其他驻留在相同设备上的应用。&&& 采用Implicit Grant方式获取Access Token的授权验证流程又被称为User-Agent Flow,适用于所有无Server端配合的应用(由于应用往往位于一个User Agent里,如浏览器里面,因此这类应用在某些平台下又被称为Client-Side Application),如手机/桌面客户端程序、浏览器插件等,以及基于JavaScript等脚本客户端脚本语言实现的应用,他们的一个共同特点是,应用无法妥善保管其应用密钥(App Secret Key),如果采取Authorization Code模式,则会存在泄漏其应用密钥的可能性。其流程示意图如下: &&&& +----------+&&&& | Resource |&&&& |& Owner&& |&&&& |&&&&&&&&& |&&&& +----------+&&&&&&&&& ^&&&&&&&&& |&&&&&&&& (B)&&&& +----|-----+&&&&&&&&& Client Identifier&&&& +---------------+&&&& | & & & & &+----(A)-- & Redirection URI ---&|&&&&&&&&&&&&&& |&&&& |& User-&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | Authorization |&&&& |& Agent & |----(B)-- User authenticates --&|&&&& Server&&& |&&&& |&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&&&&&&&&&&& |&&&& |&&&&&&&&& |&---(C)--- Redirection URI ----&|&&&&&&&&&&&&&& |&&&& |&&&&&&&&& |&&&&&&&&& with Access Token&&&& +---------------+&&&& |&&&&&&&&& |&&&&&&&&&&& in Fragment&&&& |&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&&& |&&&&&&&&& |----(D)--- Redirection URI ----&|&& Web-Hosted& |&&&& |&&&&&&&&& |&&&&&&&&& without Fragment&&&&& |&&&& Client&&& |&&&& |&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&& Resource&& |&&&& |&&&& (F)& |&---(E)------- Script ---------&|&&&&&&&&&&&&&& |&&&& |&&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&&& +-|--------+&&&&&& |&&& |&&&&& (A)& (G) Access Token&&&&&& |&&& |&&&&&& ^&&& v&&&& +---------+&&&& |&&&&&&&& |&&&& |& Client |&&&& |&&&&&&&& |&&&& +---------+&&&& 注:说明步骤(A)和(B)的直线因为通过用户代理而被分为两部分。&&&& 图2:隐式许可流程&&& 图2中的所示流程包含以下步骤:&&& (A)客户端通过向授权端点引导资源所有者的用户代理开始流程。客户端包括它的客户端标识、请求范围、本地状态和重定向URI,一旦访问被许可(或拒绝)授权服务器将传送用户代理回到该URI。&&& (B)授权服务器验证资源拥有者的身份(通过用户代理),并确定资源所有者是否授予或拒绝客户端的访问请求。&&& (C)假设资源所有者许可访问,授权服务器使用之前(在请求时或客户端注册时)提供的重定向URI重定向用户代理回到客户端。重定向URI在URI片段中包含访问令牌。&&& (D)用户代理顺着重定向指示向Web托管的客户端资源发起请求(按RFC2616该请求不包含片段)。用户代理在本地保留片段信息。&&& (E)Web托管的客户端资源返回一个网页(通常是带有嵌入式脚本的HTML文档),该网页能够访问包含用户代理保留的片段的完整重定向URI并提取包含在片段中的访问令牌(和其他参数)。&&& (F)用户代理在本地执行Web托管的客户端资源提供的提取访问令牌的脚本。&&& (G)用户代理传送访问令牌给客户端。&&&& Tips: 1. 一般不需提供 client_secret,仅需 client_id,单用户同样需要认证。&&& && 2. Implicit Grant Type 不支持 refresh_token(或可自行实现)机制。&&& && 3. THE FIRST TIME THE USER AUTHENTICATES YOUR APP USING IMPLICIT GRANT FLOW STORE THE ACCESS TOKEN! Once you have the access token do not try to re-authenticate. Your access token that you stored should continue to work!&&& &&&&& 一旦获取 access_token (存在于 redirect_uri 的 fragment 中, 即 uri 中的 # 部分),Client 需要自己存储 access_token。&&& && 4. 比较适用于 Client-Side Application,如手机/桌面客户端程序、浏览器插件等&&& oauth2-server-php 对本授权方式的实现如下:&&& 1. 这种授权方式包含于 Authorization Code Grant (是对 Authorization Code Grant 方式的简化)。&& &&& 初始化 OAuth2Controller 时, 只需向 OAuth2 Server 添加 AuthorizationCode 类型的授权即可,如下:&&&&&&& $server-&addGrantType(new OAuth2\GrantType\AuthorizationCode($storage));&&& Authorization Code 默认不支持 Implicit Grant, 需要将 Server.php 第 104 行的 'allow_implicit' 修改为 'true' 以开启 Implicit 授权。&&& 2. 获取 access_token&&& /oauth2/index.php?r=oauth2/authorize&response_type=token&client_id=testclient&state=xyz&redirect_uri=&&& 参数: response_type=token (必须, 固定值)& & & & & & &client_id (必须)& & & & & & &redirect_uri 可选& & & & & & &scope&&& 可选& & & & & & &state&&& 推荐&&& 注意:response_type = token 而不是 code, 因为隐式授权不用获取 authorization code。&&& 返回:&&& &&& 成功:&&& &&& &&& 需要用户先点击授权按钮。&&& &&& &&& SUCCESS! Authorization Code: ?#access_token=9f0c38b475e51ccd3&&& &&& 出错: redirect_uri 与注册的 client redirect_uri 不匹配。&&& &&& &&& {"error":"redirect_uri_mismatch","error_description":"The redirect URI provided is missing or does not match","error_uri":"http:\/\/tools.ietf.org\/html\/rfc6749#section-3.1.2"}&&& access_token 存在于 redirect_uri 中的片段(fragment)中, 即&#&符号之后,client 需要自己提取片段中的 access_token 并注意保存。开发人员应注意,一些用户代理不支持在HTTP&Location&HTTP响应标头字段中包含片段组成部分。这些客户端需要使用除了3xx重定向响应以外的其他方法来重定向客户端&&-例如,返回一个HTML页面,其中包含一个具有链接到重定向URI的动作的&继续&按钮。&&& 第三种认证方式: Resource Owner Password Credentials (资源所有者密码凭证许可)&&& 资源所有者密码凭据许可类型适合于资源所有者与客户端具有信任关系的情况,如设备操作系统或高级特权应用。当启用这种许可类型时授权服务器应该特别关照且只有当其他流程都不可用时才可以。&&& 这种许可类型适合于能够获得资源所有者凭据(用户名和密码,通常使用交互的形式)的客户端。通过转换已存储的凭据至访问令牌,它也用于迁移现存的使用如HTTP基本或摘要身份验证的直接身份验证方案的客户端至OAuth。&&&& +----------+&&&& | Resource |&&&& |& Owner&& |&&&& |&&&&&&&&& |&&&& +----------+&&&&&&&&& v&&&&&&&&& |&&& Resource Owner&&&&&&&& (A) Password Credentials&&&&&&&&& |&&&&&&&&& v&&&& +---------+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&&& |&&&&&&&& |&--(B)---- Resource Owner -------&|&&&&&&&&&&&&&& |&&&& |&&&&&&&& |&&&&&&&& Password Credentials&&&& | Authorization |&&&& | Client& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&& Server&&& |&&&& |&&&&&&&& |&--(C)---- Access Token ---------&|&&&&&&&&&&&&&& |&&&& |&&&&&&&& |&&& (w/ Optional Refresh Token)&& |&&&&&&&&&&&&&& |&&&& +---------+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&&& 图3:资源所有者密码凭据流程&&&& 图3中的所示流程包含以下步骤:&&& (A)资源所有者提供给客户端它的用户名和密码。&&& (B)通过包含从资源所有者处接收到的凭据,客户端从授权服务器的令牌端点请求访问令牌。当发起请求时,客户端与授权服务器进行身份验证。&&& (C)授权服务器对客户端进行身份验证,验证资源所有者的凭证,如果有效,颁发访问令牌。&&& Tips: 客户端一旦获得访问令牌必须丢弃凭据。oauth2-server-php 对 Resource Owner Password Credentials 的实现如下:&&& 1. 首先在 Oauth2Controller 的构造函数中添加对于 Resource Owner Password Credentials 授权方式的支持,加入以下代码:&&& $server-&addGrantType(new OAuth2\GrantType\UserCredentials($storage));&&& 2. 获取 access_token :&&& curl -u testclient:testpass /oauth2/index.php?r=oauth2/token -d 'grant_type=password&username=rereadyou&password=rereadyou'&&& 返回:&&& &&& {"access_token":"66decd1b1f63efe7cc352ce",&&& &&& &"expires_in":3600,&&& &&& &"token_type":"bearer",&&& &&& &"scope":null,&&& &&& &"refresh_token":"b5fa0c24e786e37e7ce7d6e2fa0d7c"}&&& Tips:&&& Github 上 oauth2-server-php 提供的 sql schema user 表里面没有 user_id 字段[12],需要自行添加该字段(主键, auto_increment)。&&& &&& user 表设计使用 sha1 摘要方式,没有添加 salt。&&& &&& &&& &&& 在 Pdo.php 中有:&&& &&& // plaintext passwords are bad!& Override this for your application&&& &&& protected function checkPassword($user, $password)&&& &&& {&&& &&& &&& return $user['password'] == sha1($password);&&& &&& }&&& &&& 对于用户认证需要改写这个函数。第四种认证方式: Client Credentials Grant (客户端凭证许可)&&& 当客户端请求访问它所控制的,或者事先与授权服务器协商(所采用的方法超出了本规范的范围)的其他资源所有者的受保护资源,客户端可以只使用它的客户端凭据(或者其他受支持的身份验证方法)请求访问令牌。&&& 客户端凭据许可类型必须只能由机密客户端使用。&&&& +---------+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&&& |&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&&&&&&&&&&& |&&&& |&&&&&&&& |&--(A)- Client Authentication ---&| Authorization |&&&& | Client& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&& Server&&& |&&&& |&&&&&&&& |&--(B)---- Access Token ---------&|&&&&&&&&&&&&&& |&&&& |&&&&&&&& |&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |&&&&&&&&&&&&&& |&&&& +---------+&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& +---------------+&&&& 图4:客户端凭证流程&&&& 图4中的所示流程包含以下步骤:&&& (A)客户端与授权服务器进行身份验证并向令牌端点请求访问令牌。&&& (B)授权服务器对客户端进行身份验证,如果有效,颁发访问令牌。&&&& Tips: 这是最简单的认证方式。&&&& 由于客户端身份验证被用作授权许可,所以不需要其他授权请求。&&& 实现如下:&&& 1. 在 Oauth2Controller 中添加对 client credentials 认证方式的支持:&&& $server-&addGrantType(new OAuth2\GrantType\ClientCredentials($storage));&&& &&& 2. 获取 access_token:&&& curl -u testclient:testpass /oauth2/index.php?r=oauth2/token -d 'grant_type=client_credentials'&&& &&& 提交参数: grant_type&&& REQUIRED.& Value MUST be set to "client_credentials".&&& &&& && scope&&& OPTIONAL.& &&& 返回:&&& &&& {"access_token": "f3c30def0d28c633eeb0bbd9d5ff9",&&& &&& &"expires_in":3600,&&& &&& &"token_type":"bearer",&&& &&& &"scope":null}&&& Tips: Client 直接使用自己的 client id 和 client_secret 获取 access_&&& &&&&& RFC6749规范指明[10] clinet crendentials 客户端认证取得 access_token 时不包括 refresh_token。&&& &&&&& 不过,oauth2-server-php 提供了控制开关,在 OAuth2/GrantTypes/ClientCredentials.php 第 33 行[11],&&& &&&&& 默认 $includeRefreshToken = 设置为 true, 则可在颁发 access_token 同时颁发 refresh_token。&&& 第三部分: access_token 类型说明&&& 客户端在操作数据资源时(通过 api)需要向 server 出示 access_token,关于如何出示 access_token 和 access_token 类型由以下部分说明。&&& IETF rfc 6749 中说明的 access_token 类型有两种:Bearer type 和 MAC type。&&& 由于 OAuth2-Server-php 对于 MAC 类型的 access_token 尚在开发之中,以下仅对最常使用的 Bearer 类型 access_token 进行说明。&&& 有三种在资源请求中发送 bearer access_token 资源给资源服务器的方法[13]。客户端不能在每次请求中使用超过一个方法传输令牌。&&& a. 当在由HTTP/1.1[RFC2617]定义的&Authorization&请求头部字段中发送访问令牌时,客户端使用&Bearer&身份验证方案来传输访问令牌。&&& &&& GET /resource HTTP/1.1&&& &&& Host: &&& &&& Authorization: Bearer mF_9.B5f-4.1JqM&&& 客户端应该使用带有&Bearer&HTTP授权方案的&Authorization&请求头部字段发起带有不记名令牌的身份验证请求。资源服务器必须支持此方法。&&& &&& b. 表单编码的主体参数&&&&&& 当在HTTP请求实体主体中发送访问令牌时,客户端采用&access_token&参数向请求主体中添加访问令牌。客户端不能使用此方法,除非符合下列所有条件:&&&&&& HTTP请求的实体头部含有设置为&application/x-www-form-urlencoded&的&Content-Type&头部字段。&&&&&& 实体主体遵循HTML4.01[W3C.REC-html401-]定义的&application/x-www-form-urlencoded&内容类型的编码要求。&&&&&& HTTP请求实体主体是单一的部分。&&&&&& 在实体主体中编码的内容必须完全由ASCII[USASCII]字符组成。&&&&&& HTTP请求方法是请求主体定义为其定义的语法。尤其是,这意味着&GET&方法不能被使用。&&&&&& &&&&&& 客户端采用传输层安全发起如下的HTTP请求:&&& &&& &&& &&& POST /resource HTTP/1.1&&& &&& Host: &&& &&& Content-Type: application/x-www-form-urlencoded&&& &&& access_token=mF_9.B5f-4.1JqM&&& c. 当在HTTP请求URI中发送访问令牌时,客户端采用&access_token&参数,向&统一资源标示符(URI):通用语法&RFC3986定义的请求URI查询部分添加访问令牌。&&&&&& 例如,客户端采用传输层安全发起如下的HTTP请求:&&& &&& GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1&&& &&& Host: &&&&&& 它不应该被使用,除非不能在&Authorization&请求头部字段或HTTP请求实体主体中传输访问令牌。&&& &&& 以上在 rfc6750 规范中提出的三种 access_token 的使用方式。推荐使用第一种方案。Bearer token 的使用需要借助 TLS 来确保 access_token 传输时的安全性。第四部分: 使用 Bearer access_token 的调用 api&&& 1. 使用 refresh_token 换取 access_token:&&& &curl -u testclient:testpass /oauth2/index.php?r=oauth2/token -d "grant_type=refresh_token&refresh_token=1ce1a52dff3b5ab836aecb86bf31b6f"&&& 返回: &&& &&& {"access_token":"50540a7ead3a27cdb458b6cdc38df25f64da18f1",&&& &&& &"expires_in":3600,&&& &&& &"token_type":"bearer",&&& &&& &"scope":null}&&&&&&& 这里没有新的 refresh_token,需要进行配置以重新获取 refresh_token,可修改 OAuth2/GrantType/RefreshToken.php 中的 RefreshToken class __construct 方法中的 'always_issue_new_refresh_token' =& true 来开启颁发新的 refresh_token。&&& Tips: IETF rfc2649 中对于 refresh_token section 的部分说明,&&& &&& POST /token HTTP/1.1&&& &&& Host: &&& &&& Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW&&& &&& Content-Type: application/x-www-form-urlencoded&&& &&& grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&&& 需要提供客户端的 client_id 和 client_secret, grant_type 值必须是 refresh_token。&&& access_token 有效期内不能使用 refresh_token 换取新的 access_token。&&& 2. 使用 access_token:&&& a. client app 使用 access_token 获取 resource 信息。&&& oauth2-server 验证 access_token:&&& &&& curl /oauth2/index.php?r=oauth2/verifytoken -d 'access_token=aea4add5e4117bedd6e07ccc3f402'&&& 返回:&&& &&& {"result":"success",&&& &&& &"message":"your access token is valid."&&& &&& }&&& 这个部分只是为了验证 access token 的有效性,client app 并不应该直接调用该方法,而是在请求资源时有server自行调用,根据判断结果进行不同处理。&&& 可以在 Oauth2 extension 的 Server.php 中来修改 access_token 的有效期。&&& 3. scope&&& scope 需要服务端确定具体的可行操作。&&& scope 用来确定 client 所能进行的操作权限。项目中操作权限由 srbac 进行控制, Oauth2 中暂不做处理。&&& 4. state&&& state 为 client app 在第一步骤中获取 authorization code 时向 OAuth2 Server 传递并由 OAuth2 Server 返回的随机哈希参数。state 参数主要用来防止跨站点请求伪造(Cross Site Request Forgery, CSRF),相关讨论可参见本文最后的参考【7】和【8】。&&& References:&&& [0] &&& [1]
& &&&& [2]
&&&&& [4] &&&& [5]
&&&&& [6] &&& [7]
&&&&& [8] &&&& [9]
&&&&& [11] &&&& [12]
阅读(...) 评论()}

我要回帖

更多关于 yii oauth2.0 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信