• 基于PHP构建OAuth 2.0 服务端 认证平台


    OAuth2.0 认证服务

    安装

    你可以在github上下载OAuth Server PHP,也可以用下列命令下载,不过内容都是一样的

    mkdir my-oauth2-walkthrough
    cd my-oauth2-walkthrough
    git clone https://github.com/bshaffer/oauth2-server-php.git -b master

    下载后放在根目录,因为这只是个测试!

    在这之后配置数据库

    Database: `oauth2db`

      1 --
      2 -- Database: `oauth2db`
      3 --
      4 
      5 -- --------------------------------------------------------
      6 
      7 --
      8 -- 表的结构 `oauth_access_tokens`
      9 --
     10 
     11 CREATE TABLE IF NOT EXISTS `oauth_access_tokens` (
     12   `access_token` varchar(40) NOT NULL,
     13   `client_id` varchar(80) NOT NULL,
     14   `user_id` varchar(255) DEFAULT NULL,
     15   `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     16   `scope` varchar(2000) DEFAULT NULL
     17 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     18 
     19 -- --------------------------------------------------------
     20 
     21 --
     22 -- 表的结构 `oauth_authorization_codes`
     23 --
     24 
     25 CREATE TABLE IF NOT EXISTS `oauth_authorization_codes` (
     26   `authorization_code` varchar(40) NOT NULL,
     27   `client_id` varchar(80) NOT NULL,
     28   `user_id` varchar(255) DEFAULT NULL,
     29   `redirect_uri` varchar(2000) DEFAULT NULL,
     30   `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     31   `scope` varchar(2000) DEFAULT NULL
     32 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     33 
     34 -- --------------------------------------------------------
     35 
     36 --
     37 -- 表的结构 `oauth_clients`
     38 --
     39 
     40 CREATE TABLE IF NOT EXISTS `oauth_clients` (
     41   `client_id` varchar(80) NOT NULL,
     42   `client_secret` varchar(80) NOT NULL,
     43   `redirect_uri` varchar(2000) NOT NULL,
     44   `grant_types` varchar(80) DEFAULT NULL,
     45   `scope` varchar(100) DEFAULT NULL,
     46   `user_id` varchar(80) DEFAULT NULL
     47 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     48 
     49 --
     50 -- 转存表中的数据 `oauth_clients`
     51 --
     52 
     53 INSERT INTO `oauth_clients` (`client_id`, `client_secret`, `redirect_uri`, `grant_types`, `scope`, `user_id`) VALUES
     54 ('testclient', 'testpass', 'https://user.endv.cn/', 'authorization_code', '', '');
     55 
     56 -- --------------------------------------------------------
     57 
     58 --
     59 -- 表的结构 `oauth_jwt`
     60 --
     61 
     62 CREATE TABLE IF NOT EXISTS `oauth_jwt` (
     63   `client_id` varchar(80) NOT NULL,
     64   `subject` varchar(80) DEFAULT NULL,
     65   `public_key` varchar(2000) DEFAULT NULL
     66 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     67 
     68 -- --------------------------------------------------------
     69 
     70 --
     71 -- 表的结构 `oauth_refresh_tokens`
     72 --
     73 
     74 CREATE TABLE IF NOT EXISTS `oauth_refresh_tokens` (
     75   `refresh_token` varchar(40) NOT NULL,
     76   `client_id` varchar(80) NOT NULL,
     77   `user_id` varchar(255) DEFAULT NULL,
     78   `expires` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     79   `scope` varchar(2000) DEFAULT NULL
     80 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     81 
     82 -- --------------------------------------------------------
     83 
     84 --
     85 -- 表的结构 `oauth_scopes`
     86 --
     87 
     88 CREATE TABLE IF NOT EXISTS `oauth_scopes` (
     89   `scope` text,
     90   `is_default` tinyint(1) DEFAULT NULL
     91 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     92 
     93 -- --------------------------------------------------------
     94 
     95 --
     96 -- 表的结构 `oauth_users`
     97 --
     98 
     99 CREATE TABLE IF NOT EXISTS `oauth_users` (
    100   `username` varchar(255) NOT NULL,
    101   `password` varchar(2000) DEFAULT NULL,
    102   `first_name` varchar(255) DEFAULT NULL,
    103   `last_name` varchar(255) DEFAULT NULL
    104 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    View Code

     我们来建立一个server.php文件来配置server,这个文件可以被所有的终端来调用。

     1 <?php
     2   /** 配置 */ 
     3 $dsn= 'mysql:dbname=test;host=localhost';
     4 $username = 'test';
     5 $password = 'test';
     6  
     7 // 错误报告(这毕竟是一个演示!)
     8 ini_set('display_errors',1);error_reporting(E_ALL);
     9  
    10 // 自动加载
    11 require_once('oauth2-server-php/src/OAuth2/Autoloader.php');
    12 OAuth2Autoloader::register();
    13 $storage = new OAuth2StoragePdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    14  
    15 // 通过存储对象或对象数组存储的oauth2服务器类
    16 $server = new OAuth2Server($storage);
    17  
    18 // 授权码 有效期只有30秒
    19 $server->addGrantType(new OAuth2GrantTypeAuthorizationCode($storage));
    20 
    21 // 客户端证书  
    22 $server->addGrantType(new OAuth2GrantTypeClientCredentials($storage));
    23 
    24 // 用户凭据
    25 $server->addGrantType(new OAuth2GrantTypeUserCredentials($storage));
    26 // 刷新令牌  启用这个会报错,原因未知
    27 // $server->addGrantType(new OAuth2GrantTypeRefreshToken($refreshStorage))

    记得配置数据库的用户名和密码 test

    Token控制器

    下面,我们将建立一个Token控制器,这个控制器URI将会返回OAuth2的Token给客户端

    <?php
     // include our OAuth2 Server object
    require_once __DIR__.'/server.php';
     
    $server->handleTokenRequest(OAuth2Request::createFromGlobals())->send();

     测试Token控制器

    需要先创建一条记录,来注册一个新的应用 (上面脚本中已插入,需要先删除!)

    INSERT INTO `oauth_clients` (`client_id`, `client_secret`, `redirect_uri`, `grant_types`, `scope`, `user_id`) VALUES
    ('testclient', 'testpass', 'https://user.endv.cn/', 'authorization_code', '', '');

     然后用命令行调用

    curl -u testclient:testpass https://user.endv.cn/token.php --data "grant_type=authorization_code&code=f8ef50221f7817f3e01d2d6c31a33f3c40db76a5"

     这里的URL只是示例,实地操作要确定能找到这个token.php

    如果运行正常,则显示

    {"access_token":"84c66d296308aad20aa5e065743d2fe30426b046","expires_in":3600,"token_type":"Bearer","scope":null,"refresh_token":"d49cd4d7d875065888fc457c7c714cab9fcf9d69"}

     资源控制器的建立和测试

    你创建了Token,你需要在API中测试它:

    resource.php

    <?php
     
     //资源控制器的建立和测试 
    require_once __DIR__.'/server.php';
    
    if (!$server->verifyResourceRequest(OAuth2Request::createFromGlobals())) {
        $server->getResponse()->send();
        die;
    }
    $token = $server->getAccessTokenData(OAuth2Request::createFromGlobals());
    echo "User ID associated with this token is {$token['user_id']}";
    
    echo json_encode(array('success' => true, 'message' => '您访问了我的API!'));
     
      

     然后运行下面的命令,记得将YOUR_TOKEN替换成刚才得到的token,还有确保URL的正确

    curl https://user.endv.cn/resource.php --data 'access_token=YOUR_TOKEN'

     如果没出问题,则会得到下面的结果

    {"success":true,"message":"You accessed my APIs!"}

     认证控制器的创建和测试

    验证控制器是OAuth2的杀手锏,它允许你的平台帮助用户验证第三方应用
    它不像第一个例子中直接返回一个Access Token,这里稍微复杂一点:

    然后在浏览器中打开这个URL

    https://user.endv.cn/authorize.php?response_type=code&client_id=testclient&state=xyz

     你将会看到一个表单,当你选择yes的时候会弹出你所获得的Authorization Code

     现在你可以用这个Authorization Code来刚才建立的token.php获得TOKEN,命令如下

    curl -u testclient:testpass https://user.endv.cn/token.php -d 'grant_type=authorization_code&code=YOUR_CODE'

     就像刚才一样,你获得了一个TOKEN

    {"access_token":"6f05ad622a3d32a5a81aee5d73a5826adb8cbf63","expires_in":3600,"token_type":"bearer","scope":null}

     请在30秒内完成这个操作,因为Authorization Code的有效期只有30秒

    用Access Token联系本地用户

    当你认证了一个用户并且分派了一个Token之后,你可能想知道彼时到底是哪个用户使用了这个Token
    你可以使用handleAuthorizeRequest的可选参数user_id来完成,修改你的authorize.php文件

    $userid = 1234; // A value on your server that identifies the user
    $server->handleAuthorizeRequest($request, $response, $is_authorized, $userid)

     这样一来,用户ID就伴随Token一起存进数据库了

    当Token被客户端使用的时候,你就知道是哪个用户了,修改 resource.php 来完成任务

    测试:点我测试

    测试到此结束,后续客户端的建立。


  • 相关阅读:
    线阵相机、镜头及光源的选型
    查看mysql数据库容量大小
    mysql 表分区操作
    VC++ 全局变量定义
    sql按半小时统计
    sqlserver/mysql按天、按小时、按分钟统计连续时间段数据
    相机光学 接圈
    Excel中如何锁定部分单元格内容不被修改?
    VC++ 捕获不了异常
    mysql 数据库存储路径更改
  • 原文地址:https://www.cnblogs.com/endv/p/7868549.html
Copyright © 2020-2023  润新知