• OAuth 2.0 Server PHP实现示例


    需求
    实现三方OAuth2.0授权登录

    使用OAuth服务
    OAuth 2.0 Server PHP

    环境
    nginx
    mysql
    php

    框架
    Yii

    一 安装

    项目目录下安装应用
    composer.phar require bshaffer/oauth2-server-php "^1.10"
    

    二 构建数据结构


    注意 user表需要自定义

    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),
      PRIMARY KEY (username)
    );
    
    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
    );
    

    三 代码实现

    <?php
    /**
     * Created by PhpStorm.
     * User: parker
     * Date: 2020/9/8
     * Time: 7:08 下午
     *
     * 使用 OAuth 2.0 Server PHP 搭建三方授权服务
     * 相关文档地址 https://bshaffer.github.io/oauth2-server-php-docs/
     * 本服务使用 授权码形式
     * 授权码(authorization code)方式,指的是第三方应用先申请一个授权码,然后再用该码获取令牌。
     * 这种方式是最常用的流程,安全性也最高,它适用于那些有后端的 Web 应用。授权码通过前端传送,令牌则是储存在后端,而且所有与资源服务器的通信都在后端完成。这样的前后端分离,可以避免令牌泄漏。
     *
     */
    
    namespace backendcontrollersapi;
    
    
    use commonlibLController;
    use commonlibLError;
    use commonmodelsadminAdminModel;
    use OAuth2GrantTypeAuthorizationCode;
    
    use OAuth2Request;
    use OAuth2Response;
    use OAuth2Server;
    use OAuth2StoragePdo;
    use yiihelpersJson;
    use Yii;
    
    class OauthController extends LController
    {
    
        public $enableCsrfValidation = false;
        /** @var Pdo $storage */
        public $storage;
        /** @var Server $server */
        public $server;
        /** @var Request $request */
        public $request;
        /** @var Response $response */
        public $response;
    
        public function init()
        {
    
            $this->storage  = new Pdo([
                'dsn' => 'mysql:host=10.0.80.10;dbname=ylsrc_admin',
                'username' => 'root',
                'password' => '2Q5@a5X6fh'
            ], [
                'client_table' => 'src_oauth_clients',
                'access_token_table' => 'src_oauth_access_tokens',
                'refresh_token_table' => 'src_oauth_refresh_tokens',
                'code_table' => 'src_oauth_authorization_codes',
                'user_table' => 'src_admin',
                'scope_table'  => 'src_oauth_scopes',
                'public_key_table'  => 'src_oauth_public_keys',
            ]);
            $this->server   = new Server($this->storage);
            $this->request  = Request::createFromGlobals();
            $this->response = new Response();
        }
    
    
        /**
         * 获取授权码(测试使用生产环境服务添加到登录接口)
         *
         * 获取链接
         * GET http://usrc.com/api/oauth/get-code?response_type=code&client_id=1&state=xyz
         * response_type    必填  请求类型
         * client_id        必填  三方授权id
         * state            必填  回调验证字段
         *
         * 响应方式为跳转到src_oauth_clients表对应id条目设置的redirect_url跳转连接返回第三方应用, 并且携带code
         * 示例:对应的redirect_url为 https://host.com 那么对应的跳转连接为(state未使用)
         * https://host.com?code=d53d363349951c29593b722a7d2fb05c054f5e65&state=xyz
         *
         */
        public function actionGetCode()
        {
            $uid = Yii::$app->user->id;
            if($uid){
                $this->server->addGrantType(new AuthorizationCode($this->storage)); // or any grant type you like!
                $this->server->validateAuthorizeRequest($this->request, $this->response);
                $this->server->handleAuthorizeRequest($this->request, $this->response, true, $uid);
                $this->response->send();
            }else{
                $this->ajaxReturn( LError::NO_PERMISSION, LError::getErrMsgByCode( LError::NO_PERMISSION ), [] );
            }
    
        }
    
        /**
         * 获取access_toke
         * 获取链接
         * POST     http://usrc.com/api/oauth/get-token
         * data
         * grant_type       必填  请求类型    authorization_code
         * client_id        必填  三方授权id
         * client_secret    必填  三方授权秘钥
         * code             必填  上一步获取的授权码
         *
         * return
         *
         * {
         * "access_token": "b2d91c2764bdde79e4f1e92349b969e8ee031e8a",
         * "expires_in": 3600,
         * "token_type": "Bearer",
         * "scope": null,
         * "refresh_token": "d9293e82c22523ad6500d6b584b484cc3aeb4736"
         * }
         */
        public function actionGetToken()
        {
            $response = $this->server->handleTokenRequest($this->request);
            $response->send();
        }
    
        /**
         * 使用token获取用户信息
         * 获取连接
         * GET  http://usrc.com/api/oauth/get-user-info?access_token=b2d91c2764bdde79e4f1e92349b969e8ee031e8a
         *
         * access_token 上一步获取的token
         *
         */
        public function actionGetUserInfo()
        {
            if (!$this->server->verifyResourceRequest($this->request)) {
                $this->server->getResponse()->send();
            }else{
                $token = $this->server->getAccessTokenData($this->request);
                $user  = AdminModel::findIdentity($token['user_id']);
                $data  = [
                    'id' => $user->id,
                    'username' => $user->account_name,
                    'mobile' => $user->mobile,
                    'email' => $user->email,
                ];
    
                echo Json::encode($data);
            }
    
        }
    }

     

    参考文献

    OAuth2.0 官方文档  https://oauth.net/2/

    OAuth 2.0 Server PHP 官方文档 https://bshaffer.github.io/oauth2-server-php-docs/

    OAuth2.0的一个简单解释 阮一峰 http://www.ruanyifeng.com/blog/2019/04/oauth_design.html

    OAuth2.0的四种方式 阮一峰 http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html

     
  • 相关阅读:
    ODBC是什么
    node学习连接和网站
    MongoDB--连接客户端和服务
    css页面布局--三栏(两边固定中间自适应&两边自适应中间固定)
    MongoDB--搭建mongodb服务器
    MongoDB--编译文件
    MongoDB--运行环境
    Ubuntu下搜狗输入法乱码
    从命令行控制计算机屏幕
    CPU风扇转速异常
  • 原文地址:https://www.cnblogs.com/haizizhu/p/13648429.html
Copyright © 2020-2023  润新知