国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Maison php教程 php手冊(cè) 使用 OAuth2-Server-php 在 Yii 框架上搭建 OAuth2 Server

使用 OAuth2-Server-php 在 Yii 框架上搭建 OAuth2 Server

Aug 18, 2016 am 08:57 AM

原文轉(zhuǎn)自?http://www.cnblogs.com/ldms/p/4565547.html

?

Yii 有很多 extension 可以使用,在查看了 Yii 官網(wǎng)上提供的與 OAuth 相關(guān)的擴(kuò)展后,發(fā)現(xiàn)了幾個(gè) OAuth2 的客戶端擴(kuò)展,但是并沒有找到可以作為 OAuth2 Server 的擴(kuò)展。因?yàn)?Yii 是組織良好的易于擴(kuò)展的框架,所以完全可以集成其它的 PHP OAuth2 Server 實(shí)現(xiàn)方案。在 OAuth.net/2/ 官網(wǎng)上,提供了幾個(gè) PHP 實(shí)現(xiàn)的 OAuth2 Server。這里使用第一個(gè) OAuth2-Server-php 來作為 Yii 框架的 OAuth2 Server 擴(kuò)展,需要進(jìn)行一些必要的整合操作,主要是編寫一個(gè)類來接受 client 訪問和頒發(fā) access_token 等。

第一部分: 數(shù)據(jù)庫準(zhǔn)備

??? OAuth2-Server-php? 使用的數(shù)據(jù)庫結(jié)構(gòu)采用 Github 上的 oauth2-server-php README.md 提供的表結(jié)構(gòu)(Schema),一共有五張表:

????mysql> show tables;
??? +--------------------------+
? ? | Tables_in_oauth2 ? ? ? ? |
??? +--------------------------+
??? | oauth_access_token?????? |
??? | oauth_authorization_code |
??? | oauth_client???????????? |
??? | oauth_refresh_token????? |
??? | user???????????????????? |
??? +--------------------------+
??? 5 rows in set (0.00 sec)
????
??? 各表的名字說明了表中存取的內(nèi)容,表名可自定義,自定義位置為:OAuth2/Storage/Pdo.php 48行的 config 數(shù)組中,因?yàn)檫@里采用的是 mysql 數(shù)據(jù)庫,所以需要修改的是 Pdo,若是采用其它的存儲(chǔ)方案,如 Redis,則自行修改對(duì)應(yīng)文件即可。注意這里的數(shù)據(jù)庫名稱是都是單數(shù)形式。

??? 使用以下 sql 語句創(chuàng)建這5個(gè)表,并添加一個(gè)測(cè)試 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', '8551be07bab21f3933e8177538d411e43b78dbcc', 'bo', 'zhang');


第二部分: 認(rèn)證方案及實(shí)現(xiàn)

??? OAuth2 RFC 6749 規(guī)范提供了四種基本認(rèn)證方案,以下針對(duì)這四種認(rèn)證方案以及它們?cè)诒緦?shí)現(xiàn)中的使用方式進(jìn)行分別說面。

第一種認(rèn)證方式: Authorization Code Grant (授權(quán)碼認(rèn)證)

??? 授權(quán)碼通過使用授權(quán)服務(wù)器做為客戶端與資源所有者的中介而獲得??蛻舳瞬皇侵苯訌馁Y源所有者請(qǐng)求授權(quán),而是引導(dǎo)資源所有者至授權(quán)服務(wù)器(由在RFC2616中定義的用戶代理),授權(quán)服務(wù)器之后引導(dǎo)資源所有者帶著授權(quán)碼回到客戶端。

??? 在引導(dǎo)資源所有者攜帶授權(quán)碼返回客戶端前,授權(quán)服務(wù)器會(huì)鑒定資源所有者身份并獲得其授權(quán)。由于資源所有者只與授權(quán)服務(wù)器進(jìn)行身份驗(yàn)證,所以資源所有者的憑據(jù)不需要與客戶端分享。

??? 授權(quán)碼提供了一些重要的安全益處,例如驗(yàn)證客戶端身份的能力,以及向客戶端直接的訪問令牌的傳輸而非通過資源所有者的用戶代理來傳送它而潛在暴露給他人(包括資源所有者)。

??? 授權(quán)碼許可類型用于獲得訪問令牌和刷新令牌并未機(jī)密客戶端進(jìn)行了優(yōu)化。由于這是一個(gè)基于重定向的流程,客戶端必須能夠與資源所有者的用戶代理(通常是Web瀏覽器)進(jìn)行交互并能夠接收來自授權(quán)服務(wù)器的傳入請(qǐng)求(通過重定向)。

? 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????????????????? |
??? ?|???????? |???????????????????????????????????????????? |
??? ?|???????? |??? ?+---------+?????? (w/ Optional Refresh Token)

??? 注:說明步驟(A)、(B)和(C)的直線因?yàn)橥ㄟ^用戶代理而被分為兩部分。
??? 圖1:授權(quán)碼流程

??? 在圖1中所示的流程包括以下步驟:

??? (A)客戶端通過向授權(quán)端點(diǎn)引導(dǎo)資源所有者的用戶代理開始流程。客戶端包括它的客戶端標(biāo)識(shí)、請(qǐng)求范圍、本地狀態(tài)和重定向URI,一旦訪問被許可(或拒絕)授權(quán)服務(wù)器將傳送用戶代理回到該URI。
??? (B)授權(quán)服務(wù)器驗(yàn)證資源擁有者的身份(通過用戶代理),并確定資源所有者是否授予或拒絕客戶端的訪問請(qǐng)求。
??? (C)假設(shè)資源所有者許可訪問,授權(quán)服務(wù)器使用之前(在請(qǐng)求時(shí)或客戶端注冊(cè)時(shí))提供的重定向URI重定向用戶代理回到客戶端。重定向URI包括授權(quán)碼和之前客戶端提供的任何本地狀態(tài)。
??? (D)客戶端通過包含上一步中收到的授權(quán)碼從授權(quán)服務(wù)器的令牌端點(diǎn)請(qǐng)求訪問令牌。當(dāng)發(fā)起請(qǐng)求時(shí),客戶端與授權(quán)服務(wù)器進(jìn)行身份驗(yàn)證。客戶端包含用于獲得授權(quán)碼的重定向URI來用于驗(yàn)證。
??? (E)授權(quán)服務(wù)器對(duì)客戶端進(jìn)行身份驗(yàn)證,驗(yàn)證授權(quán)代碼,并確保接收的重定向URI與在步驟(C)中用于重定向客戶端的URI相匹配。如果通過,授權(quán)服務(wù)器響應(yīng)返回訪問令牌與可選的刷新令牌。

??? 過程實(shí)現(xiàn):
??? 1.??? client app 使用 app id 獲取 authorization code:

??? www.yii.com/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 的構(gòu)造方法配置參數(shù)來自定義 authorization_code 有效時(shí)間。
??? client_id 是之前注冊(cè)在本 Server 上的應(yīng)用名稱,這屬于客戶端管理范疇。?
??? 這一步需要進(jìn)行用戶(資源所有者)登錄 OAuth2 Server 來完成授權(quán)操作。用戶登錄屬用戶管理范疇,不屬 OAuth2 Server 中應(yīng)編寫的功能。
??? 用戶登錄后可選擇自己可以向 client app 開放的操作(授權(quán))。
??? 這一步綁定過程中,從安全角度來考慮應(yīng)強(qiáng)制用戶重新輸入用戶名密碼確認(rèn)綁定,不要直接讀取當(dāng)前用戶session進(jìn)行綁定。?

??? 2. 獲取 access_token:
?????? client app 使用 authorization code 換取 access_token

???????curl -u testclient:testpass www.yii.com/oauth2/index.php?r=oauth2/token -d "grant_type=authorization_code&code=$authcode

?????? 返回:
??? ??? 成功:
??? ????{"access_token":"aea4a1059d3194a3dd5e4117bedd6e07ccc3f402",
??? ??? ?"expires_in":3600,
??? ??? ?"token_type":"bearer",
??? ??? ?"scope":null,
??? ??? ?"refresh_token":"269a623f54171e8598b1852eefcf115f4882b820"
??? ??? }

??? ??? 失?。?br>??? ????{"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 中的構(gòu)造函數(shù)配置中進(jìn)行修改。
????
???

第二種認(rèn)證方式: Implicit (隱式認(rèn)證)
????
??? 隱式授權(quán)類型被用于獲取訪問令牌(它不支持發(fā)行刷新令牌),并對(duì)知道操作具體重定向URI的公共客戶端進(jìn)行優(yōu)化。這些客戶端通常在瀏覽器中使用諸如JavaScript的腳本語言實(shí)現(xiàn)。

??? 由于這是一個(gè)基于重定向的流程,客戶端必須能夠與資源所有者的用戶代理(通常是Web瀏覽器)進(jìn)行交互并能夠接收來自授權(quán)服務(wù)器的傳入請(qǐng)求(通過重定向)。

??? 不同于客戶端分別請(qǐng)求授權(quán)和訪問令牌的授權(quán)碼許可類型,客戶端收到訪問令牌作為授權(quán)請(qǐng)求的結(jié)果。

??? 隱式許可類型不包含客戶端身份驗(yàn)證而依賴于資源所有者在場(chǎng)和重定向URI的注冊(cè)。因?yàn)樵L問令牌被編碼到重定向URI中,它可能會(huì)暴露給資源所有者和其他駐留在相同設(shè)備上的應(yīng)用。

??? 采用Implicit Grant方式獲取Access Token的授權(quán)驗(yàn)證流程又被稱為User-Agent Flow,適用于所有無Server端配合的應(yīng)用(由于應(yīng)用往往位于一個(gè)User Agent里,如瀏覽器里面,因此這類應(yīng)用在某些平臺(tái)下又被稱為Client-Side Application),如手機(jī)/桌面客戶端程序、瀏覽器插件等,以及基于JavaScript等腳本客戶端腳本語言實(shí)現(xiàn)的應(yīng)用,他們的一個(gè)共同特點(diǎn) 是,應(yīng)用無法妥善保管其應(yīng)用密鑰(App Secret Key),如果采取Authorization Code模式,則會(huì)存在泄漏其應(yīng)用密鑰的可能性。其流程示意圖如下:?

???? +----------+
???? | Resource |
???? |? Owner?? |
???? |????????? |
???? +----------+
????????? ^
????????? |
???????? (B)
???? +----|-----+????????? Client Identifier???? +---------------+
???? | ? ? ? ? ?+----(A)-- & Redirection URI --->|?????????????? |
???? |? User-?? |??????????????????????????????? | Authorization |
???? |? Agent ? |----(B)-- User authenticates -->|???? Server??? |
???? |????????? |??????????????????????????????? |?????????????? |
???? |????????? |???? |????????? |????????? with Access Token???? +---------------+
???? |????????? |??????????? in Fragment
???? |????????? |??????????????????????????????? +---------------+
???? |????????? |----(D)--- Redirection URI ---->|?? Web-Hosted? |
???? |????????? |????????? without Fragment????? |???? Client??? |
???? |????????? |??????????????????????????????? |??? Resource?? |
???? |???? (F)? |???? |????????? |??????????????????????????????? +---------------+
???? +-|--------+
?????? |??? |
????? (A)? (G) Access Token
?????? |??? |
?????? ^??? v
???? +---------+
???? |???????? |
???? |? Client |
???? |???????? |
???? +---------+

???? 注:說明步驟(A)和(B)的直線因?yàn)橥ㄟ^用戶代理而被分為兩部分。

???? 圖2:隱式許可流程

??? 圖2中的所示流程包含以下步驟:

??? (A)客戶端通過向授權(quán)端點(diǎn)引導(dǎo)資源所有者的用戶代理開始流程。客戶端包括它的客戶端標(biāo)識(shí)、請(qǐng)求范圍、本地狀態(tài)和重定向URI,一旦訪問被許可(或拒絕)授權(quán)服務(wù)器將傳送用戶代理回到該URI。
??? (B)授權(quán)服務(wù)器驗(yàn)證資源擁有者的身份(通過用戶代理),并確定資源所有者是否授予或拒絕客戶端的訪問請(qǐng)求。
??? (C)假設(shè)資源所有者許可訪問,授權(quán)服務(wù)器使用之前(在請(qǐng)求時(shí)或客戶端注冊(cè)時(shí))提供的重定向URI重定向用戶代理回到客戶端。重定向URI在URI片段中包含訪問令牌。
??? (D)用戶代理順著重定向指示向Web托管的客戶端資源發(fā)起請(qǐng)求(按RFC2616該請(qǐng)求不包含片段)。用戶代理在本地保留片段信息。
??? (E)Web托管的客戶端資源返回一個(gè)網(wǎng)頁(通常是帶有嵌入式腳本的HTML文檔),該網(wǎng)頁能夠訪問包含用戶代理保留的片段的完整重定向URI并提取包含在片段中的訪問令牌(和其他參數(shù))。
??? (F)用戶代理在本地執(zhí)行Web托管的客戶端資源提供的提取訪問令牌的腳本。
??? (G)用戶代理傳送訪問令牌給客戶端。

???? Tips: 1. 一般不需提供 client_secret,僅需 client_id,單用戶同樣需要認(rèn)證。
??? ?? 2. Implicit Grant Type 不支持 refresh_token(或可自行實(shí)現(xiàn))機(jī)制。
??? ?? 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 需要自己存儲(chǔ) access_token。
??? ?? 4. 比較適用于 Client-Side Application,如手機(jī)/桌面客戶端程序、瀏覽器插件等

??? oauth2-server-php 對(duì)本授權(quán)方式的實(shí)現(xiàn)如下:

??? 1. 這種授權(quán)方式包含于 Authorization Code Grant (是對(duì) Authorization Code Grant 方式的簡(jiǎn)化)。
???
??? 初始化 OAuth2Controller 時(shí), 只需向 OAuth2 Server 添加 AuthorizationCode 類型的授權(quán)即可,如下:
????????$server->addGrantType(new OAuth2\GrantType\AuthorizationCode($storage));

??? Authorization Code 默認(rèn)不支持 Implicit Grant, 需要將 Server.php 第 104 行的 'allow_implicit' 修改為 'true' 以開啟 Implicit 授權(quán)。


??? 2. 獲取 access_token

??? http://www.yii.com/oauth2/index.php?r=oauth2/authorize&response_type=token&client_id=testclient&state=xyz&redirect_uri=www.baidu.com

??? 參數(shù): response_type=token (必須, 固定值)
? ? ? ? ? ? ?client_id (必須)
? ? ? ? ? ? ?redirect_uri 可選
? ? ? ? ? ? ?scope??? 可選
? ? ? ? ? ? ?state??? 推薦
??? 注意:response_type = token 而不是 code, 因?yàn)殡[式授權(quán)不用獲取 authorization code。
??? 返回:
??? ??? 成功:
??? ??? ??? 需要用戶先點(diǎn)擊授權(quán)按鈕。
??? ??? ??? SUCCESS! Authorization Code: www.baidu.com?#access_token=9f0c38b475e51ccd3

??? ??? 出錯(cuò): redirect_uri 與注冊(cè)的 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)中, 即‘#’符號(hào)之后,client 需要自己提取片段中的 access_token 并注意保存。開發(fā)人員應(yīng)注意,一些用戶代理不支持在HTTP“Location”HTTP響應(yīng)標(biāo)頭字段中包含片段組成部分。這些客戶端需要使用除了3xx 重定向響應(yīng)以外的其他方法來重定向客戶端——-例如,返回一個(gè)HTML頁面,其中包含一個(gè)具有鏈接到重定向URI的動(dòng)作的“繼續(xù)”按鈕。
????

第三種認(rèn)證方式: Resource Owner Password Credentials (資源所有者密碼憑證許可)

??? 資源所有者密碼憑據(jù)許可類型適合于資源所有者與客戶端具有信任關(guān)系的情況,如設(shè)備操作系統(tǒng)或高級(jí)特權(quán)應(yīng)用。當(dāng)啟用這種許可類型時(shí)授權(quán)服務(wù)器應(yīng)該特別關(guān)照且只有當(dāng)其他流程都不可用時(shí)才可以。

??? 這種許可類型適合于能夠獲得資源所有者憑據(jù)(用戶名和密碼,通常使用交互的形式)的客戶端。通過轉(zhuǎn)換已存儲(chǔ)的憑據(jù)至訪問令牌,它也用于遷移現(xiàn)存的使用如HTTP基本或摘要身份驗(yàn)證的直接身份驗(yàn)證方案的客戶端至OAuth。

???? +----------+
???? | Resource |
???? |? Owner?? |
???? |????????? |
???? +----------+
????????? v
????????? |??? Resource Owner
???????? (A) Password Credentials
????????? |
????????? v
???? +---------+????????????????????????????????? +---------------+
???? |???????? |>--(B)---- Resource Owner ------->|?????????????? |
???? |???????? |???????? Password Credentials???? | Authorization |
???? | Client? |????????????????????????????????? |???? Server??? |
???? |???????? |???? |???????? |??? (w/ Optional Refresh Token)?? |?????????????? |
???? +---------+????????????????????????????????? +---------------+

???? 圖3:資源所有者密碼憑據(jù)流程

???? 圖3中的所示流程包含以下步驟:

??? (A)資源所有者提供給客戶端它的用戶名和密碼。
??? (B)通過包含從資源所有者處接收到的憑據(jù),客戶端從授權(quán)服務(wù)器的令牌端點(diǎn)請(qǐng)求訪問令牌。當(dāng)發(fā)起請(qǐng)求時(shí),客戶端與授權(quán)服務(wù)器進(jìn)行身份驗(yàn)證。

??? (C)授權(quán)服務(wù)器對(duì)客戶端進(jìn)行身份驗(yàn)證,驗(yàn)證資源所有者的憑證,如果有效,頒發(fā)訪問令牌。


??? Tips: 客戶端一旦獲得訪問令牌必須丟棄憑據(jù)。

oauth2-server-php 對(duì) Resource Owner Password Credentials 的實(shí)現(xiàn)如下:

??? 1. 首先在 Oauth2Controller 的構(gòu)造函數(shù)中添加對(duì)于 Resource Owner Password Credentials 授權(quán)方式的支持,加入以下代碼:

????$server->addGrantType(new OAuth2\GrantType\UserCredentials($storage));

??? 2. 獲取 access_token :

????curl -u testclient:testpass www.yii.com/oauth2/index.php?r=oauth2/token -d 'grant_type=password&username=rereadyou&password=rereadyou'

??? 返回:
??? ??? {"access_token":"66decd1b10891db5f8f63efe7cc352ce326895c6",
??? ??? ?"expires_in":3600,
??? ??? ?"token_type":"bearer",
??? ??? ?"scope":null,
??? ??? ?"refresh_token":"b5fa0c24e786e37e7ce7d6e2f911805dc65a0d7c"}

??? Tips:??? Github 上 oauth2-server-php 提供的 sql schema user 表里面沒有 user_id 字段[12],需要自行添加該字段(主鍵, auto_increment)。
??? ??? user 表設(shè)計(jì)使用 sha1 摘要方式,沒有添加 salt。
??? ????
??? ??? 在 Pdo.php 中有:
??? ????// plaintext passwords are bad!? Override this for your application
??? ??? protected function checkPassword($user, $password)
??? ??? {
??? ??? ??? return $user['password'] == sha1($password);
??? ??? }
??? ??? 對(duì)于用戶認(rèn)證需要改寫這個(gè)函數(shù)。



第四種認(rèn)證方式: Client Credentials Grant (客戶端憑證許可)

??? 當(dāng)客戶端請(qǐng)求訪問它所控制的,或者事先與授權(quán)服務(wù)器協(xié)商(所采用的方法超出了本規(guī)范的范圍)的其他資源所有者的受保護(hù)資源,客戶端可以只使用它的客戶端憑據(jù)(或者其他受支持的身份驗(yàn)證方法)請(qǐng)求訪問令牌。

??? 客戶端憑據(jù)許可類型必須只能由機(jī)密客戶端使用。

???? +---------+????????????????????????????????? +---------------+
???? |???????? |????????????????????????????????? |?????????????? |
???? |???????? |>--(A)- Client Authentication --->| Authorization |
???? | Client? |????????????????????????????????? |???? Server??? |
???? |???????? |???? |???????? |????????????????????????????????? |?????????????? |
???? +---------+????????????????????????????????? +---------------+

???? 圖4:客戶端憑證流程

???? 圖4中的所示流程包含以下步驟:

??? (A)客戶端與授權(quán)服務(wù)器進(jìn)行身份驗(yàn)證并向令牌端點(diǎn)請(qǐng)求訪問令牌。

??? (B)授權(quán)服務(wù)器對(duì)客戶端進(jìn)行身份驗(yàn)證,如果有效,頒發(fā)訪問令牌。

???? Tips: 這是最簡(jiǎn)單的認(rèn)證方式。

???? 由于客戶端身份驗(yàn)證被用作授權(quán)許可,所以不需要其他授權(quán)請(qǐng)求。

??? 實(shí)現(xiàn)如下:
??? 1. 在 Oauth2Controller 中添加對(duì) client credentials 認(rèn)證方式的支持:

????$server->addGrantType(new OAuth2\GrantType\ClientCredentials($storage));
????
??? 2. 獲取 access_token:

????curl -u testclient:testpass www.yii.com/oauth2/index.php?r=oauth2/token -d 'grant_type=client_credentials'
????
??? 提交參數(shù): grant_type??? REQUIRED.? Value MUST be set to "client_credentials".
??? ??? ?? scope??? OPTIONAL.??
??? 返回:
??? ????{"access_token": "f3c30def0d28c633e34921b65388eb0bbd9d5ff9",
??? ??? ?"expires_in":3600,
??? ??? ?"token_type":"bearer",
??? ??? ?"scope":null}

??? Tips: Client 直接使用自己的 client id 和 client_secret 獲取 access_token;
??? ????? RFC6749規(guī)范指明[10] clinet crendentials 客戶端認(rèn)證取得 access_token 時(shí)不包括 refresh_token。
??? ????? 不過,oauth2-server-php 提供了控制開關(guān),在 OAuth2/GrantTypes/ClientCredentials.php 第 33 行[11],
??? ????? 默認(rèn) $includeRefreshToken = false; 設(shè)置為 true, 則可在頒發(fā) access_token 同時(shí)頒發(fā) refresh_token。
????

第三部分: access_token 類型說明
??? 客戶端在操作數(shù)據(jù)資源時(shí)(通過 api)需要向 server 出示 access_token,關(guān)于如何出示 access_token 和 access_token 類型由以下部分說明。
??? IETF rfc 6749 中說明的 access_token 類型有兩種:Bearer type 和 MAC type。
??? 由于 OAuth2-Server-php 對(duì)于 MAC 類型的 access_token 尚在開發(fā)之中,以下僅對(duì)最常使用的 Bearer 類型 access_token 進(jìn)行說明。

??? 有三種在資源請(qǐng)求中發(fā)送 bearer access_token 資源給資源服務(wù)器的方法[13]??蛻舳瞬荒茉诿看握?qǐng)求中使用超過一個(gè)方法傳輸令牌。
??? a. 當(dāng)在由HTTP/1.1[RFC2617]定義的“Authorization”請(qǐng)求頭部字段中發(fā)送訪問令牌時(shí),客戶端使用“Bearer”身份驗(yàn)證方案來傳輸訪問令牌。

??? ??? GET /resource HTTP/1.1
??? ??? Host: server.example.com
??? ??? Authorization: Bearer mF_9.B5f-4.1JqM

??? 客戶端應(yīng)該使用帶有“Bearer”HTTP授權(quán)方案的“Authorization”請(qǐng)求頭部字段發(fā)起帶有不記名令牌的身份驗(yàn)證請(qǐng)求。資源服務(wù)器必須支持此方法。
????
??? b. 表單編碼的主體參數(shù)
?????? 當(dāng)在HTTP請(qǐng)求實(shí)體主體中發(fā)送訪問令牌時(shí),客戶端采用“access_token”參數(shù)向請(qǐng)求主體中添加訪問令牌。客戶端不能使用此方法,除非符合下列所有條件:
?????? HTTP請(qǐng)求的實(shí)體頭部含有設(shè)置為“application/x-www-form-urlencoded”的“Content-Type”頭部字段。
?????? 實(shí)體主體遵循HTML4.01[W3C.REC-html401-19991224]定義的“application/x-www-form-urlencoded”內(nèi)容類型的編碼要求。
?????? HTTP請(qǐng)求實(shí)體主體是單一的部分。
?????? 在實(shí)體主體中編碼的內(nèi)容必須完全由ASCII[USASCII]字符組成。
?????? HTTP請(qǐng)求方法是請(qǐng)求主體定義為其定義的語法。尤其是,這意味著“GET”方法不能被使用。
???????
?????? 客戶端采用傳輸層安全發(fā)起如下的HTTP請(qǐng)求:
??? ????
??? ??? POST /resource HTTP/1.1
??? ??? Host: server.example.com
??? ??? Content-Type: application/x-www-form-urlencoded
??? ??? access_token=mF_9.B5f-4.1JqM

??? c. 當(dāng)在HTTP請(qǐng)求URI中發(fā)送訪問令牌時(shí),客戶端采用“access_token”參數(shù),向“統(tǒng)一資源標(biāo)示符(URI):通用語法”RFC3986定義的請(qǐng)求URI查詢部分添加訪問令牌。

?????? 例如,客戶端采用傳輸層安全發(fā)起如下的HTTP請(qǐng)求:

??? ??? GET /resource?access_token=mF_9.B5f-4.1JqM HTTP/1.1
??? ??? Host: server.example.com

?????? 它不應(yīng)該被使用,除非不能在“Authorization”請(qǐng)求頭部字段或HTTP請(qǐng)求實(shí)體主體中傳輸訪問令牌。
????
??? 以上在 rfc6750 規(guī)范中提出的三種 access_token 的使用方式。推薦使用第一種方案。Bearer token 的使用需要借助 TLS 來確保 access_token 傳輸時(shí)的安全性。


第四部分: 使用 Bearer access_token 的調(diào)用 api

??? 1. 使用 refresh_token 換取 access_token:
?????curl -u testclient:testpass www.yii.com/oauth2/index.php?r=oauth2/token -d "grant_type=refresh_token&refresh_token=1ce1a52dff3b5ab836ae25714c714cb86bf31b6f"

??? 返回:?
??? ????{"access_token":"50540a7ead3a27cdb458b6cdc38df25f64da18f1",
??? ??? ?"expires_in":3600,
??? ??? ?"token_type":"bearer",
??? ??? ?"scope":null}
??????? 這里沒有新的 refresh_token,需要進(jìn)行配置以重新獲取 refresh_token,可修改 OAuth2/GrantType/RefreshToken.php 中的 RefreshToken class __construct 方法中的 'always_issue_new_refresh_token' => true 來開啟頒發(fā)新的 refresh_token。
??? Tips: IETF rfc2649 中對(duì)于 refresh_token section 的部分說明,
??? ????POST /token HTTP/1.1
??? ??? Host: server.example.com
??? ??? 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 有效期內(nèi)不能使用 refresh_token 換取新的 access_token。

??? 2. 使用 access_token:
??? a. client app 使用 access_token 獲取 resource 信息。
??? oauth2-server 驗(yàn)證 access_token:
??? ????curl www.yii.com/oauth2/index.php?r=oauth2/verifytoken -d 'access_token=aea4a1059d3194a3dd5e4117bedd6e07ccc3f402'

??? 返回:
??? ????{"result":"success",
??? ??? ?"message":"your access token is valid."
??? ??? }??? 這個(gè)部分只是為了驗(yàn)證 access token 的有效性,client app 并不應(yīng)該直接調(diào)用該方法,而是在請(qǐng)求資源時(shí)有server自行調(diào)用,根據(jù)判斷結(jié)果進(jìn)行不同處理。
??? 可以在 Oauth2 extension 的 Server.php 中來修改 access_token 的有效期。

??? 3. scope
??? scope 需要服務(wù)端確定具體的可行操作。
??? scope 用來確定 client 所能進(jìn)行的操作權(quán)限。項(xiàng)目中操作權(quán)限由 srbac 進(jìn)行控制, Oauth2 中暫不做處理。

??? 4. state
??? state 為 client app 在第一步驟中獲取 authorization code 時(shí)向 OAuth2 Server 傳遞并由 OAuth2 Server 返回的隨機(jī)哈希參數(shù)。state 參數(shù)主要用來防止跨站點(diǎn)請(qǐng)求偽造(Cross Site Request Forgery, CSRF),相關(guān)討論可參見本文最后的參考【7】和【8】。

????
References:

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefa?on, veuillez contacter admin@php.cn

Outils d'IA chauds

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Article chaud

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Sujets chauds

Tutoriel PHP
1502
276