zoukankan      html  css  js  c++  java
  • oauth2-server-php-docs 食谱

    一步一步的演练

    以下说明提供详细的演练,以帮助您启动并运行OAuth2服务器。要查看实现此库的现有OAuth2服务器的代码库,请查看OAuth2 Demo

    初始化您的项目

    为您的项目创建一个目录,并拉入这个库

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

    定义你的模式

    现在使用以下模式创建默认数据库:

    MySQL / SQLite / PostgreSQL / MS SQL Server

    sql
    CREATE TABLE oauth_clients (
      client_id             VARCHAR(80)   NOT NULL,
      client_secret         VARCHAR(80),
      redirect_uri          VARCHAR(2000),
      grant_types           VARCHAR(80),
      scope                 VARCHAR(4000),
      user_id               VARCHAR(80),
      PRIMARY KEY (client_id)
    );
    
    CREATE TABLE oauth_access_tokens (
      access_token         VARCHAR(40)    NOT NULL,
      client_id            VARCHAR(80)    NOT NULL,
      user_id              VARCHAR(80),
      expires              TIMESTAMP      NOT NULL,
      scope                VARCHAR(4000),
      PRIMARY KEY (access_token)
    );
    
    CREATE TABLE oauth_authorization_codes (
      authorization_code  VARCHAR(40)     NOT NULL,
      client_id           VARCHAR(80)     NOT NULL,
      user_id             VARCHAR(80),
      redirect_uri        VARCHAR(2000),
      expires             TIMESTAMP       NOT NULL,
      scope               VARCHAR(4000),
      id_token            VARCHAR(1000),
      PRIMARY KEY (authorization_code)
    );
    
    CREATE TABLE oauth_refresh_tokens (
      refresh_token       VARCHAR(40)     NOT NULL,
      client_id           VARCHAR(80)     NOT NULL,
      user_id             VARCHAR(80),
      expires             TIMESTAMP       NOT NULL,
      scope               VARCHAR(4000),
      PRIMARY KEY (refresh_token)
    );
    
    CREATE TABLE oauth_users (
      username            VARCHAR(80),
      password            VARCHAR(80),
      first_name          VARCHAR(80),
      last_name           VARCHAR(80),
      email               VARCHAR(80),
      email_verified      BOOLEAN,
      scope               VARCHAR(4000)
    );
    
    CREATE TABLE oauth_scopes (
      scope               VARCHAR(80)     NOT NULL,
      is_default          BOOLEAN,
      PRIMARY KEY (scope)
    );
    
    CREATE TABLE oauth_jwt (
      client_id           VARCHAR(80)     NOT NULL,
      subject             VARCHAR(80),
      public_key          VARCHAR(2000)   NOT NULL
    );

    ##引导您的OAuth2服务器

    我们需要创建和配置我们的OAuth2服务器对象。这将被我们的应用程序中的所有端点使用。命名这个文件server.php

    $dsn      = 'mysql:dbname=my_oauth2_db;host=localhost';
    $username = 'root';
    $password = '';
    
    // error reporting (this is a demo, after all!)
    ini_set('display_errors',1);error_reporting(E_ALL);
    
    // Autoloading (composer is preferred, but for this example let's just do this)
    require_once('oauth2-server-php/src/OAuth2/Autoloader.php');
    OAuth2Autoloader::register();
    
    // $dsn is the Data Source Name for your database, for exmaple "mysql:dbname=my_oauth2_db;host=localhost"
    $storage = new OAuth2StoragePdo(array('dsn' => $dsn, 'username' => $username, 'password' => $password));
    
    // Pass a storage object or array of storage objects to the OAuth2 server class
    $server = new OAuth2Server($storage);
    
    // Add the "Client Credentials" grant type (it is the simplest of the grant types)
    $server->addGrantType(new OAuth2GrantTypeClientCredentials($storage));
    
    // Add the "Authorization Code" grant type (this is where the oauth magic happens)
    $server->addGrantType(new OAuth2GrantTypeAuthorizationCode($storage));

    注意:一定要定义$dsn$username$password变量是数据库的相应值。

    创建一个令牌控制器

    接下来,我们将创建令牌控制器这是将OAuth2.0令牌返回给客户端的URI。以下是文件中令牌控制器的示例token.php

    // include our OAuth2 Server object
    require_once __DIR__.'/server.php';
    
    // Handle a request for an OAuth2.0 Access Token and send the response to the client
    $server->handleTokenRequest(OAuth2Request::createFromGlobals())->send();

    Congratulatons!你已经创建了一个令牌控制器你想看到它的行动?运行以下SQL来创建一个OAuth客户端:

    sql
    INSERT INTO oauth_clients (client_id, client_secret, redirect_uri) VALUES ("testclient", "testpass", "http://fake/");

    现在从命令行运行以下命令:

    文本
    curl -u testclient:testpass http://localhost/token.php -d 'grant_type=client_credentials'

    注意:http://localhost/token.php假设你token.php在本地机器上有文件,并且你已经设置了“localhost”虚拟主机来指向它。这可能会因您的应用程序而异。

    如果一切正常,你应该收到这样的回应:

    json
    {"access_token":"03807cb390319329bdf6c777d4dfae9c0d3b3c35","expires_in":3600,"token_type":"bearer","scope":null}

    创建一个资源控制器

    现在您正在创建令牌,您将需要在API中验证它们。以下是文件中资源控制器的示例resource.php

    // include our OAuth2 Server object
    require_once __DIR__.'/server.php';
    
    // Handle a request to a resource and authenticate the access token
    if (!$server->verifyResourceRequest(OAuth2Request::createFromGlobals())) {
        $server->getResponse()->send();
        die;
    }
    echo json_encode(array('success' => true, 'message' => 'You accessed my APIs!'));

    现在从命令行运行以下命令:

    文本
    curl http://localhost/resource.php -d 'access_token=YOUR_TOKEN'

    注意:使用上一步中的“access_token”中返回的值代替YOUR_TOKEN

    如果一切顺利的话,你应该会收到这样的回复:

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

    创建一个授权控制器

    授权控制器是OAuth2的“杀手级功能”,允许您的用户授权第三方应用程序。与第一个令牌控制器示例中发生的直接发送访问令牌不同,在本示例中,授权控制器用于在用户授权请求后才发布令牌。创建authorize.php

    // include our OAuth2 Server object
    require_once __DIR__.'/server.php';
    
    $request = OAuth2Request::createFromGlobals();
    $response = new OAuth2Response();
    
    // validate the authorize request
    if (!$server->validateAuthorizeRequest($request, $response)) {
        $response->send();
        die;
    }
    // display an authorization form
    if (empty($_POST)) {
      exit('
    <form method="post">
      <label>Do You Authorize TestClient?</label><br />
      <input type="submit" name="authorized" value="yes">
      <input type="submit" name="authorized" value="no">
    </form>');
    }
    
    // print the authorization code if the user has authorized your client
    $is_authorized = ($_POST['authorized'] === 'yes');
    $server->handleAuthorizeRequest($request, $response, $is_authorized);
    if ($is_authorized) {
      // this is only here so that you get to see your code in the cURL request. Otherwise, we'd redirect back to the client
      $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40);
      exit("SUCCESS! Authorization Code: $code");
    }
    $response->send();

    现在将以下URL粘贴到您的浏览器中

    文本
    http://localhost/authorize.php?response_type=code&client_id=testclient&state=xyz

    系统会提示您使用授权表单,并在点击“是”时收到授权码

    授权码现在可以用来从您以前创建的token.php端点接收访问令牌只需使用返回的授权码调用此端点:

    文本
    curl -u testclient:testpass http://localhost/token.php -d 'grant_type=authorization_code&code=YOUR_CODE'

    和以前一样,您将收到一个访问令牌:

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

    注意:请务必迅速执行此操作,因为授权码会在30秒内过期!

    将本地用户与访问令牌关联起来

    一旦你对一个用户进行了身份验证并发布了一个访问令牌(比如上面的Authorize Controller示例),那么当你使用访问令牌时,你可能会想知道哪个用户是访问令牌的。请查看 用户标识文档以获取有关如何执行此操作的信息。

    使用外部客户端测试您的授权控制器

    如果您想使用“真实”客户端来测试授权控制器,请查看 Google OAuth2 Playground示例

    Google Playground

    使用Google OAuth 2.0 Playground测试您的服务器

    一旦你在野外的互联网上建立你的服务器,你会想检查它与独立的客户端。一种方法是使用Google OAuth 2.0 Playground

    假设你已经设置了一个授权控制器,你可以按如下方式进行测试:

    1. 使用上面的链接导航到游乐场。

    2. 点击右上角的设置按钮。

    3. 选择“服务器端”作为“OAuth流程”,选择“自定义”作为“OAuth端点”。

    4. 在授权端点中,输入授权控制器的URL(例如https://domain.com/authorize.php)。

    5. 在令牌端点中,输入令牌控制器的URL(例如https://domain.com/token.php)。

    6. 为访问令牌位置选择“授权标头w /承载前缀”。

    7. 输入客户端ID和密码(如果使用以前的文档示例,则使用testclient和testpass)。

    8. 在左侧的文本框中输入“basic”,然后单击“授权API”。你应该被带到你的网站,你可以授权请求,之后你应该返回到游乐场。

    9. 点击“兑换令牌授权码”即可接收令牌(您需要在30秒内完成)。

    10. 在右边的回应应该显示访问令牌。输入资源页面的URL(例如https://domain.com/resource.php)。

    11. 添加你想要的任何可选参数,然后点击“发送请求”。如果您以前使用过相同的代码,则应该看到相同的响应:

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

    Drupal的

    对于drupal集成,请参阅bojanzOAuth2服务器模块

    Zend框架

    为了这个库与Zend框架2整合,你可以使用这些模块之一:* OAuth2Provider由弗兰茨·德利恩* ZF2-的oauth2提供商由格伦·施密特

    
    

    Laravel

    在Laravel 4中查看这个Laravel演示应用程序来实现这个库。

    一步一步的演练

    1. 创建你的Laravel项目(例如composer create-project laravel/laravel --prefer-dist
    2. 使用Composer:composer require bshaffer/oauth2-server-php安装OAuth2服务器和HTTPFoundation网桥依赖关系composer require bshaffer/oauth2-server-httpfoundation-bridge
    3. 设置您的数据库并运行提供的迁移(请参阅https://github.com/julien-c/laravel-oauth2-server/commit/b290d4f699b9758696444e2d62dd82f0eeedcb7d):

      php artisan db:migrate

    4. 使用提供的脚本对数据库进行种子处理:https//github.com/julien-c/laravel-oauth2-server/commit/8895c54cbf8ea8ba78aafab53a5a0409ce2f1ba2

      php artisan db:seed

    5. 设置您的OAuth2服务器。为了能够访问Laravel应用程序中任何位置的单个实例,可以将其作为单例添加:
    App::singleton('oauth2', function() {
        
        $storage = new OAuth2StoragePdo(App::make('db')->getPdo());
        $server = new OAuth2Server($storage);
        
        $server->addGrantType(new OAuth2GrantTypeClientCredentials($storage));
        $server->addGrantType(new OAuth2GrantTypeUserCredentials($storage));
        
        return $server;
    });
    1. 实施您希望实施的实际OAuth2控制器。例如令牌控制器和资源控制器:请参阅app/routes.php

    你甚至可以单元测试你的整合!下面是一个使用Guzzle的例子:https//github.com/julien-c/laravel-oauth2-server/blob/master/app/tests/OAuthTest.php

    
    

    教义

    创建客户端和访问令牌存储

    要把学说融入到你的项目中,首先要建立你的模型。我们先从客户端和访问令牌模型开始:

    yaml
    OAuthClient:
      tableName:      oauth_client
      columns:
        client_identifier:
          type:       string(50)
          notnull:    true
        client_secret:
          type:       char(20)
          notnull:    false
        redirect_uri:
          type:       string(255)
          notnull:    true
          default:    ""
    
    OAuthAccessToken:
      tableName:      oauth_access_token
      columns:
        token:
          type:       char(40)
          notnull:    true
          unique:     true
        client_identifier:
          type:       string(50)
          notnull:    true
        user_identifier:
          type:       string(100)
          notnull:    true
        expires:
          type:       timestamp
          notnull:    true
        scope:
          type:       string(50)
          notnull:    false
      relations:
        Client:
          local:        client_identifier
          foreign:      client_identifier
          class:        OAuthClient
          foreignAlias: AccessTokens
          onDelete:     CASCADE
          onUpdate:     CASCADE

    一旦你从这个模式中生成模型,你将有一个OAuthClientOAuthCleintTable类文件,以及一个OAuthAccessTokenOAuthAccessTokenTable对象。

    OAuth2StorageClientCredentialsInterfaceOAuthClientTable课堂实施

    class OAuthClientTable extends Doctrine_Table implements OAuth2StorageClientCredentialsInterface
    {
        public function getClientDetails($client_id)
        {
            $client = $this->createQuery()
                ->where('client_identifier = ?', $client_id)
                ->fetchOne(array(), Doctrine::HYDRATE_ARRAY);
    
            return $client;
        }
    
        public function checkClientCredentials($client_id, $client_secret = NULL)
        {
            $client = $this->getClientDetails($client_id);
    
            if ($client) {
                return $client['client_secret'] === sha1($client_secret);
            }
            return false;
        }
    
        public function checkRestrictedGrantType($client_id, $grant_type)
        {
            // we do not support different grant types per client in this example
            return true;
        }
    }

    现在OAuth2StorageAccessTokenInterfaceOAuthAccessTokenTable课堂实施

    class OAuthAccessTokenTable extends Doctrine_Table implements OAuth2StorageAccessTokenInterface
    {
        public function getAccessToken($oauth_token)
        {
            $token = $this->createQuery()
                ->where('token = ?', $oauth_token)
                ->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY);
    
            if ($token) {
                return array(
                   'token'     => $token['token'],
                   'client_id' => $token['client_identifier'],
                   'expires'   => strtotime($token['expires']),
                   'scope'     => $token['scope'],
                   'user_id'   => $token['user_identifier'],
                );
            }
        }
    
        public function setAccessToken($oauth_token, $client_id, $user_id, $expires, $scope = null)
        {
            $token = new OAuthAccessToken();
            $token->fromArray(array(
               'token'              => $oauth_token,
               'client_identifier'  => $client_id,
               'user_identifier'    => $user_id,
               'expires'            => date('Y-m-d H:i:s', $expires),
               'scope'              => $scope,
            ));
    
            $token->save();
        }
    }

    做得好!现在,当你创建你的OAuthServer对象的时候,把这些表传递给:

    $clientStore = Doctrine::getTable('OAuthClient');
    $tokenStore  = Doctrine::getTable('OAuthAccessToken');
    
    // Pass the doctrine storage objects to the OAuth2 server class
    $server = new OAuth2Server(array('client_credentials' => $clientStore, 'access_token' => $tokenStore));

    你做到了!你已经把你的服务器与主义联系起来了!你可以去镇使用它,但因为你只通过它client_credentialsaccess_token存储对象,你只能用client_credentials批类型:

    // will only be able to handle token requests when "grant_type=client_credentials".
    $server->addGrantType(new OAuth2GrantTypeClientCredentials($clientStore));
    
    // handle the request
    $server->handleTokenRequest(OAuth2Request::createFromGlobals())->send();

    添加授权码和刷新令牌存储----------------

    所以让我们的应用程序更加精彩一点。将以下内容添加到您的模式并生成类文件:

    yaml
    OAuthAuthorizationCode:
      tableName:      oauth_authorization_code
      columns:
        code:
          type:       char(40)
          notnull:    true
          unique:     true
        client_identifier:
          type:       string(50)
          notnull:    true
        expires:
          type:       timestamp
          notnull:    true
        user_identifier:
          type:       string(100)
          notnull:    true
        redirect_uri:
          type:       string(200)
          notnull:    true
        scope:
          type:       string(50)
          notnull:    false
      relations:
        Client:
          local:        client_identifier
          foreign:      client_identifier
          class:        OAuthClient
          foreignAlias: AuthorizationCodes
          onDelete:     CASCADE
          onUpdate:     CASCADE
    
    OAuthRefreshToken:
      tableName:      oauth_refresh_token
      columns:
        refresh_token:
          type:       char(40)
          notnull:    true
          unique:     true
        client_identifier:
          type:       string(50)
          notnull:    true
        user_identifier:
          type:       string(100)
          notnull:    true
        expires:
          type:       timestamp
          notnull:    true
        scope:
          type:       string(50)
          notnull:    false
      relations:
        Client:
          local:        client_identifier
          foreign:      client_identifier
          class:        OAuthClient
          foreignAlias: RefreshTokens
          onDelete:     CASCADE
          onUpdate:     CASCADE

    现在,我们可以实现两个接口,OAuth2StorageAuthorizationCodeInterfaceOAuth2StorageRefreshTokenInterface这将允许我们使用他们的对应授权类型。

    OAuth2StorageAuthorizationCodeInterfaceOAuthAuthorizationCodeTable课堂实施

    class OAuthAuthorizationCodeTable extends Doctrine_Table implements OAuth2StorageAuthorizationCodeInterface
    {
        public function getAuthorizationCode($code)
        {
            $auth_code = $this->createQuery()
                ->where('code = ?', $code)
                ->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY);
    
            if ($auth_code) {
                return array(
                   'code'         => $auth_code['code'],
                   'client_id'    => $auth_code['client_identifier'],
                   'user_id'      => $auth_code['web_service_username'],
                   'redirect_uri' => $auth_code['redirect_uri'],
                   'expires'      => strtotime($auth_code['expires']),
                   'scope'        => $auth_code['scope'],
                );
            }
            return null;
        }
    
        public function setAuthorizationCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null)
        {
            $auth_code = new OAuthAuthorizationCode();
            $auth_code->fromArray(array(
               'code'                 => $code,
               'client_identifier'    => $client_id,
               'web_service_username' => $user_id,
               'redirect_uri'         => $redirect_uri,
               'expires'              => date('Y-m-d H:i:s', $expires),
               'scope'                => $scope,
            ));
    
            $auth_code->save();
        }
    
        public function expireAuthorizationCode($code)
        {
            return $this->createQuery()
                ->delete()
                ->where('code = ?', $code)
                ->execute();
        }
    }

    OAuth2StorageRefreshTokenInterfaceOAuthRefreshTokenTable课堂实施

    class OAuthRefreshTokenTable extends Doctrine_Table implements OAuth2StorageRefreshTokenInterface
    {
        public function getRefreshToken($refresh_token)
        {
            $refresh_token = $this->createQuery()
                ->where('refresh_token = ?', $refresh_token)
                ->fetchOne(array(), Doctrine_Core::HYDRATE_ARRAY);
    
            if ($auth_code) {
                return array(
                   'refresh_token' => $refresh_token['refresh_token'],
                   'client_id'     => $refresh_token['client_identifier'],
                   'user_id'       => $refresh_token['user_identifier'],
                   'expires'       => strtotime($refresh_token['expires']),
                   'scope'         => $refresh_token['scope'],
                );
            }
        }
    
        public function setRefreshToken($refresh_token, $client_id, $user_id, $expires, $scope = null)
        {
            $refresh_token = new OAuthRefreshToken();
            $refresh_token->fromArray(array(
               'code'              => $code,
               'client_identifier' => $client_id,
               'user_identifier'   => $user_id,
               'expires'           => date('Y-m-d H:i:s', $expires),
               'scope'             => $scope,
            ));
    
            $refresh_token->save();
        }
    
        public function unsetRefreshToken($refresh_token)
        {
            return $this->createQuery()
                ->delete()
                ->where('refresh_token = ?', $refresh_token)
                ->execute();
        }
    }

    现在我们可以在我们的服务器上添加两个授权类型:

    $clientStore  = Doctrine::getTable('OAuthClient');
    $tokenStore   = Doctrine::getTable('OAuthAccessToken');
    $codeStore    = Doctrine::getTable('OAuthAuthorizationCode');
    $refreshStore = Doctrine::getTable('OAuthRefreshToken');
    
    // Pass the doctrine storage objects to the OAuth2 server class
    $server = new OAuth2Server(array(
        'client_credentials' => $clientStore,
        'access_token'       => $tokenStore,
        'authorization_code' => $codeStore,
        'refresh_token'      => $refreshStore,
    ));
    
    $server->addGrantType(new OAuth2GrantTypeClientCredentials($clientStorage));
    $server->addGrantType(new OAuth2GrantTypeAuthorizationCode($codeStorage));
    $server->addGrantType(new OAuth2GrantTypeRefreshToken($refreshStorage));
    
    // handle the request
    $server->handleTokenRequest(OAuth2Request::createFromGlobals())->send();

    你做到了!好吧,几乎所有的。唯一剩下的就是添加你的用户!那么,请参阅symfony文档以了解如何与之集成sfGuardUser



























  • 相关阅读:
    div 居中
    [转贴]Linux新增用户和组
    wmsys.WM_CONCAT
    [转]深刻理解Oracle数据库的启动和关闭
    [转]JAVA 程序中使用ORACLE 绑定变量( bind variable )
    考研的一些入门知识
    [转帖]什么是CPU的核心
    js空格处理函数
    [转]Vi 基础命令
    EMPTY_CLOB()/EMPTY_BLOB()使用
  • 原文地址:https://www.cnblogs.com/endv/p/7842520.html
Copyright © 2011-2022 走看看