国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

PHP下的Oauth2.0嘗試 - 授權(quán)碼授權(quán)(Authorization Code Grant)

zilu / 4038人閱讀

摘要:不太熟悉什么是的同學(xué)可以參考阮大神的文章,理解阮一峰授權(quán)碼模式授權(quán)代碼授予類型用于獲得訪問權(quán)限令牌和刷新令牌,并為機(jī)密客戶進(jìn)行了優(yōu)化。

OAuth 2.0

不太熟悉什么是OAuth2.0的同學(xué)可以參考阮大神的文章, 理解OAuth 2.0 - 阮一峰

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

     +----------+
     | 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)

   
授權(quán)碼授權(quán)開發(fā) 引入OAuth-server包
# PHP 5.3.9+ 

composer require bshaffer/oauth2-server-php "^1.10"
創(chuàng)建數(shù)據(jù)表
-- 你可使用相應(yīng)的數(shù)據(jù)庫引擎:MySQL / SQLite / PostgreSQL / MS SQL Server
-- 數(shù)據(jù)庫:oauth_test
-- 細(xì)調(diào)過表相關(guān)結(jié)構(gòu),不過你也可以參考官方:http://bshaffer.github.io/oauth2-server-php-docs/cookbook/

DROP TABLE IF EXISTS `oauth_access_tokens`;
CREATE TABLE `oauth_access_tokens` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `access_token` varchar(40) NOT NULL,
  `client_id` varchar(80) NOT NULL,
  `user_id` varchar(80) DEFAULT NULL,
  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `scope` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `IDX_ACCESS_TOKEN` (`access_token`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Table structure for oauth_authorization_codes
-- ----------------------------
DROP TABLE IF EXISTS `oauth_authorization_codes`;
CREATE TABLE `oauth_authorization_codes` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `authorization_code` varchar(40) DEFAULT "",
  `client_id` varchar(80) DEFAULT "",
  `user_id` varchar(80) DEFAULT "0",
  `redirect_uri` varchar(2000) DEFAULT "",
  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `scope` text,
  `id_token` varchar(1000) DEFAULT "",
  PRIMARY KEY (`id`),
  UNIQUE KEY `IDX_CODE` (`authorization_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of oauth_authorization_codes
-- ----------------------------

-- ----------------------------
-- Table structure for oauth_clients
-- ----------------------------
DROP TABLE IF EXISTS `oauth_clients`;
CREATE TABLE `oauth_clients` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `client_id` varchar(80) DEFAULT "",
  `client_secret` varchar(80) DEFAULT "",
  `client_name` varchar(120) DEFAULT "",
  `redirect_uri` varchar(2000) DEFAULT "",
  `grant_types` varchar(80) DEFAULT "",
  `scope` varchar(4000) DEFAULT "",
  `user_id` varchar(80) DEFAULT "0",
  PRIMARY KEY (`id`),
  KEY `IDX_APP_SECRET` (`client_id`,`client_secret`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of oauth_clients
-- ----------------------------
INSERT INTO `oauth_clients` VALUES ("1", "testclient", "123456", "測(cè)試demo", "http://sxx.qkl.local/v2/oauth/cb", "authorization_code refresh_token", "basic get_user_info upload_pic", "");

-- ----------------------------
-- Table structure for oauth_jwt 
-- ----------------------------
DROP TABLE IF EXISTS `oauth_jwt`;
CREATE TABLE `oauth_jwt` (
  `client_id` varchar(80) NOT NULL,
  `subject` varchar(80) DEFAULT NULL,
  `public_key` varchar(2000) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of oauth_jwt
-- ----------------------------

-- ----------------------------
-- Table structure for oauth_public_keys
-- ----------------------------
DROP TABLE IF EXISTS `oauth_public_keys`;
CREATE TABLE `oauth_public_keys` (
  `client_id` varchar(80) DEFAULT NULL,
  `public_key` varchar(2000) DEFAULT NULL,
  `private_key` varchar(2000) DEFAULT NULL,
  `encryption_algorithm` varchar(100) DEFAULT "RS256"
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of oauth_public_keys
-- ----------------------------

-- ----------------------------
-- Table structure for oauth_refresh_tokens
-- ----------------------------
DROP TABLE IF EXISTS `oauth_refresh_tokens`;
CREATE TABLE `oauth_refresh_tokens` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `refresh_token` varchar(40) NOT NULL,
  `client_id` varchar(80) NOT NULL DEFAULT "",
  `user_id` varchar(80) DEFAULT "",
  `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `scope` text,
  PRIMARY KEY (`id`),
  UNIQUE KEY `IDX_REFRESH_TOKEN` (`refresh_token`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Table structure for oauth_scopes
-- ----------------------------
DROP TABLE IF EXISTS `oauth_scopes`;
CREATE TABLE `oauth_scopes` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `scope` varchar(80) NOT NULL DEFAULT "",
  `is_default` tinyint(1) unsigned NOT NULL DEFAULT "0",
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of oauth_scopes
-- ----------------------------
INSERT INTO `oauth_scopes` VALUES ("1", "basic", "1");
INSERT INTO `oauth_scopes` VALUES ("2", "get_user_info", "0");
INSERT INTO `oauth_scopes` VALUES ("3", "upload_pic", "0");

-- ----------------------------
-- Table structure for oauth_users  該表是Resource Owner Password Credentials Grant所使用
-- ----------------------------
DROP TABLE IF EXISTS `oauth_users`;
CREATE TABLE `oauth_users` (
  `uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(80) DEFAULT "",
  `password` varchar(80) DEFAULT "",
  `first_name` varchar(80) DEFAULT "",
  `last_name` varchar(80) DEFAULT "",
  `email` varchar(80) DEFAULT "",
  `email_verified` tinyint(1) DEFAULT "0",
  `scope` text,
  PRIMARY KEY (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of oauth_users
-- ----------------------------
INSERT INTO `oauth_users` VALUES ("1", "qkl", "123456", "kl", "q", "", "", "");
創(chuàng)建server

Authorization Server 角色

public function _initialize()
{
    require_once dirname(APP_PATH) . "/vendor/autoload.php";
    Autoloader::register();
}

private function server()
{
    $pdo = new PDO("mysql:host=ip;dbname=oauth_test", "user", "123456");
    
    //創(chuàng)建存儲(chǔ)的方式
    $storage = new OAuth2StoragePdo($pdo);
    
    //創(chuàng)建server
    $server = new OAuth2Server($storage);

    // 添加 Authorization Code 授予類型
    $server->addGrantType(new OAuth2GrantTypeAuthorizationCode($storage));

    return $server;
}
創(chuàng)建授權(quán)頁面(基于瀏覽器)

Authorization Server 角色

User Agent 角色,常規(guī)一般基于瀏覽器

// 授權(quán)頁面和授權(quán)
public function authorize()
{
    // 該頁面請(qǐng)求地址類似:
    // http://sxx.qkl.local/v2/oauth/authorize?response_type=code&client_id=testclient&state=xyz&redirect_uri=http://sxx.qkl.local/v2/oauth/cb&scope=basic%20get_user_info%20upload_pic
    //獲取server對(duì)象
    $server = $this->server();
    $request = OAuth2Request::createFromGlobals();
    $response = new OAuth2Response();

    // 驗(yàn)證 authorize request
    // 這里會(huì)驗(yàn)證client_id,redirect_uri等參數(shù)和client是否有scope
    if (!$server->validateAuthorizeRequest($request, $response)) {
        $response->send();
        die;
    }

    // 顯示授權(quán)登錄頁面
    if (empty($_POST)) {
        //獲取client類型的storage
        //不過這里我們?cè)趕erver里設(shè)置了storage,其實(shí)都是一樣的storage->pdo.mysql
        $pdo = $server->getStorage("client");
        //獲取oauth_clients表的對(duì)應(yīng)的client應(yīng)用的數(shù)據(jù)
        $clientInfo = $pdo->getClientDetails($request->query("client_id"));
        $this->assign("clientInfo", $clientInfo);
        $this->display("authorize");
        die();
    }

    $is_authorized = true;
    // 當(dāng)然這部分常規(guī)是基于自己現(xiàn)有的帳號(hào)系統(tǒng)驗(yàn)證
    if (!$uid = $this->checkLogin($request)) {
        $is_authorized = false;
    }

    // 這里是授權(quán)獲取code,并拼接Location地址返回相應(yīng)
    // Location的地址類似:http://sxx.qkl.local/v2/oauth/cb?code=69d78ea06b5ee41acbb9dfb90500823c8ac0241d&state=xyz
    // 這里的$uid不是上面oauth_users表的uid, 是自己系統(tǒng)里的帳號(hào)的id,你也可以省略該參數(shù)
    $server->handleAuthorizeRequest($request, $response, $is_authorized, $uid);
//        if ($is_authorized) {
//            // 這里會(huì)創(chuàng)建Location跳轉(zhuǎn),你可以直接獲取相關(guān)的跳轉(zhuǎn)url,用于debug
//            $code = substr($response->getHttpHeader("Location"), strpos($response->getHttpHeader("Location"), "code=")+5, 40);
//            exit("SUCCESS! Authorization Code: $code :: " . $response->getHttpHeader("Location"));
//        }
    $response->send();
}

/**
 * 具體基于自己現(xiàn)有的帳號(hào)系統(tǒng)驗(yàn)證
 * @param $request
 * @return bool
 */
private function checkLogin($request)
{
    //todo
    if ($request->request("username") != "qkl") {
        return $uid = 0; //login faile
    }

    return $uid = 1; //login success
}
創(chuàng)建獲取token

Authorization Server 角色

// 生成并獲取token
public function token()
{
    $server = $this->server();
    $server->handleTokenRequest(OAuth2Request::createFromGlobals())->send();
    exit();
}
授權(quán)頁面

CLIENT 客戶端 角色

# 瀏覽器訪問:
http://sxx.qkl.local/v2/oauth/authorize?response_type=code&client_id=testclient&state=xyz&redirect_uri=http://sxx.qkl.local/v2/oauth/cb&scope=basic%20get_user_info%20upload_pic

授權(quán)頁面說明
# 我們換行分解下
http://sxx.qkl.local/v2/oauth/authorize?
# response_type 固定寫死 code
response_type=code&
# client_id 我們oauth_clients表的client_id值
client_id=testclient&
# state 自定義的參數(shù),隨意字符串值
state=xyz&
# redirect_uri 回調(diào)地址,這里最好是urlencode編碼,我這里演示沒編碼
# 注意這里的redirect_uri需要和oauth_clients表的redirect_uri字段做匹配處理
# redirect_uri字段可存取的方式:
# 1. http://sxx.qkl.local/v2/oauth/cb
# 2. http://sxx.qkl.local/v2/oauth/cb http://sxx.qkl.local/v2/oauth/cb2 ... 空格分割
redirect_uri=http://sxx.qkl.local/v2/oauth/cb&
# response_type 固定寫死 code
scope=basic%20get_user_info%20upload_pic
客戶端獲取code并請(qǐng)求獲取access_token

CLIENT 客戶端 角色

// 客戶端回調(diào),來自server端的Location跳轉(zhuǎn)到此
// 此處會(huì)攜帶上code和你自定義的state
public function cb()
{
    $request = OAuth2Request::createFromGlobals();
    $url = "http://sxx.qkl.local/v2/oauth/token";
    $data = [
        "grant_type" => "authorization_code",
        "code" => $request->query("code"),
        "client_id" => "testclient",
        "client_secret" => "123456",
        "redirect_uri" => "http://sxx.qkl.local/v2/oauth/cb"
    ];
    
    //todo 自定義的處理判斷
    $state = $request->query("state");

    $response = Curl::ihttp_post($url, $data);
    if (is_error($response)) {
        var_dump($response);
    }

    var_dump($response["content"]);
}

刷新token

Authorization Server 角色

// 創(chuàng)建刷新token的server
private function refresh_token_server()
{
    $pdo = new PDO("mysql:host=ip;dbname=oauth_test", "user", "123456");
    $storage = new OAuth2StoragePdo($pdo);

    $config = [
        "always_issue_new_refresh_token" => true,
        "refresh_token_lifetime"         => 2419200,
    ];

    $server = new OAuth2Server($storage, $config);

    // 添加一個(gè) RefreshToken 的類型
    $server->addGrantType(new OAuth2GrantTypeRefreshToken($storage, [
        "always_issue_new_refresh_token" => true
    ]));

    // 添加一個(gè)token的Response
    $server->addResponseType(new OAuth2ResponseTypeAccessToken($storage, $storage, [
        "refresh_token_lifetime" => 2419200,
    ]));

    return $server;
}

// 刷新token
public function refresh_token()
{
    $server = $this->refresh_token_server();
    $server->handleTokenRequest(OAuth2Request::createFromGlobals())->send();
    exit();
}
客戶端請(qǐng)求refresh_token

CLIENT 客戶端 角色

// 客戶端模擬refresh_token
public function client_refresh_token()
{
    $request = OAuth2Request::createFromGlobals();
    $url = "http://sxx.qkl.local/v2/oauth/refresh_token";
    $data = [
        "grant_type" => "refresh_token",
        "refresh_token" => "d9c5bee6a4ad7967ac044c99e40496aa2c3d28b4",
        "client_id" => "testclient",
        "client_secret" => "123456"
    ];

    $response = Curl::ihttp_post($url, $data);
    if (is_error($response)) {
        var_dump($response);
    }

    var_dump($response["content"]);
}

scope授權(quán)資源

Authorization Server 角色

這里說明下 因?yàn)樵谏厦姹韯?chuàng)建時(shí),我創(chuàng)建了3個(gè)socpe[basic,get_user_info,upload_pic]用于測(cè)試
上面我們?cè)跒g覽器訪問的授權(quán)地址上也填寫了三個(gè)權(quán)限,所以只要access_token正確在時(shí)效內(nèi),即可成功訪問

// 測(cè)試資源
public function res1()
{
    $server = $this->server();
    // Handle a request to a resource and authenticate the access token
    if (!$server->verifyResourceRequest(OAuth2Request::createFromGlobals())) {
        $server->getResponse()->send();
        die;
    }

    $token = $server->getAccessTokenData(OAuth2Request::createFromGlobals());
    
    $scopes = explode(" ", $token["scope"]);
    
    // todo 這里你可以寫成自己規(guī)則的scope驗(yàn)證
    if (!$this->checkScope("basic", $scopes)) {
        $this->ajaxReturn(["success" => false, "message" => "你沒有獲取該接口的scope"]);
    }

    $this->ajaxReturn(["success" => true, "message" => "你成功獲取該接口信息", "token"=>$token["user_id"]]);
}

// 用于演示檢測(cè)scope的方法
private function checkScope($myScope, $scopes)
{
    return in_array($myScope, $scopes);
}
客戶端postman模擬測(cè)試

正確的access_token請(qǐng)求:

錯(cuò)誤或失效的access_token請(qǐng)求:

總結(jié)
Oauth2.0整體沒什么具體的技術(shù)含量,可以參照規(guī)范實(shí)現(xiàn)即可
后續(xù)

PHP下的Oauth2.0嘗試 - OpenID Connect - 后續(xù)補(bǔ)位

附錄

Oauth2.0 - Authorization Code Grant
使用Authorization_Code獲取Access_Token - QQ互聯(lián)接入
推薦閱讀登錄授權(quán)方案 - 網(wǎng)站的無密碼登錄 - 阮一峰

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/30882.html

相關(guān)文章

  • PHP下的Oauth2.0嘗試 - OpenID Connect

    摘要:基礎(chǔ)簡(jiǎn)要而言是一種安全機(jī)制用于應(yīng)用連接到身份認(rèn)證服務(wù)器獲取用戶信息并將這些信息以安全可靠的方法返回給應(yīng)用。這些信息被保存在身份認(rèn)證服務(wù)器以確保特定的客戶端收到的信息只來自于合法的應(yīng)用平臺(tái)。 OpenID Connect OpenID Connect簡(jiǎn)介 OpenID Connect是基于OAuth 2.0規(guī)范族的可互操作的身份驗(yàn)證協(xié)議。它使用簡(jiǎn)單的REST / JSON消息流來實(shí)現(xiàn),和...

    saucxs 評(píng)論0 收藏0
  • 搭建OAuth2.0

    摘要:原因使用簡(jiǎn)單,可以很快上手,文檔齊全,功能完善。請(qǐng)求,端對(duì)應(yīng)的模板里是告知用戶,即將授予的權(quán)限列表,以及是否允許授權(quán)的按鈕。請(qǐng)求,端獲取用戶資源各種授權(quán)類型,都可以很方便支持。 前奏 系統(tǒng):Ubuntu 語言:PHP7 框架:YAF OAuth2.0:bshaffer/oauth2-server-php OAuth2.0 有很多開源代碼庫 Github 排名前兩位 thephple...

    Cheriselalala 評(píng)論0 收藏0
  • OAuth 流程與發(fā)展總結(jié) (1.0 => 1.0a => 2.0)

    摘要:如果不使用回調(diào)地址桌面或手機(jī)程序,而是通過手動(dòng)拷貝粘貼完成授權(quán)的話,那么只要攻擊者在在前面發(fā)起請(qǐng)求,就能拿到的。改進(jìn)步驟傳遞參數(shù)而不是獲取已授權(quán)步驟申請(qǐng)時(shí),必須傳遞讓參與簽名避免攻擊者假冒。 OAuth 流程與發(fā)展 (1.0 => 1.0a => 2.0) 概述 概述: 開放授權(quán)協(xié)議 作用: 允許第三方應(yīng)用訪問服務(wù)提供方中注冊(cè)的終端用戶的部分資源 下面是官方描述: [OAuth描述]...

    王偉廷 評(píng)論0 收藏0
  • OAuth 流程與發(fā)展總結(jié) (1.0 => 1.0a => 2.0)

    摘要:如果不使用回調(diào)地址桌面或手機(jī)程序,而是通過手動(dòng)拷貝粘貼完成授權(quán)的話,那么只要攻擊者在在前面發(fā)起請(qǐng)求,就能拿到的。改進(jìn)步驟傳遞參數(shù)而不是獲取已授權(quán)步驟申請(qǐng)時(shí),必須傳遞讓參與簽名避免攻擊者假冒。 OAuth 流程與發(fā)展 (1.0 => 1.0a => 2.0) 概述 概述: 開放授權(quán)協(xié)議 作用: 允許第三方應(yīng)用訪問服務(wù)提供方中注冊(cè)的終端用戶的部分資源 下面是官方描述: [OAuth描述]...

    adie 評(píng)論0 收藏0
  • OAuth2基本概念和運(yùn)作流程

    摘要:目前的版本是版,本文將對(duì)的一些基本概念和運(yùn)行流程做一個(gè)簡(jiǎn)要介紹。只要有一個(gè)第三方應(yīng)用程序被破解,就會(huì)導(dǎo)致用戶密碼泄漏,以及所有被密碼保護(hù)的數(shù)據(jù)泄漏。運(yùn)行流程客戶端向資源所有者請(qǐng)求授權(quán)。 OAuth(開放授權(quán))是一個(gè)關(guān)于授權(quán)的開放標(biāo)準(zhǔn),允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲(chǔ)的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應(yīng)用。目前的版本是2.0版,本文將...

    wyk1184 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<