OAuth2 之PHP实战

2016-11-29 Frank PHP

环境

  • >= PHP5.3
  • Yii2
  • Redis

安装

composer.phar require bshaffer/oauth2-server-php "~1.8"

运行https://github.com/bshaffer/oauth2-demo-php/blob/master/data/rebuild_db.php
生成数据库

使用(采用redis存储)

Oauth2Controller.php

<?php
/**
 * RESTful API for media
 * @copyright Copyright (c) Vastrek
 * 
 */
namespace app\controllers;

use Yii;
use yii\web\Controller;
use Predis\Client ;
/**
 * RESTful API for media 
 * 
 * @copyright Copyright &copy; 2014, Vastrek
 * @author Frank <fengxuting@gmail.com>
 * @version  1.0
 * @date 2014-11-12
 */
class Oauth2Controller extends Controller
{
    protected $_server;
    public $enableCsrfValidation = false;

    public function beforeAction($action)
    {

        if (!parent::beforeAction($action)) return false;

        //$storage = new \OAuth2\Storage\Pdo(array('dsn' => Yii::$app->db->dsn, 'username' => Yii::$app->db->username, 'password' => Yii::$app->db->password));

        $predis  = new \Predis\Client([
            'scheme' =>  Yii::$app->params['scheme'],
            'host' => Yii::$app->params['host'],
            'port' => Yii::$app->params['port'],
        ]);
        $predis->auth(Yii::$app->params['password']);
        $storage = new \OAuth2\Storage\Redis($predis);
        // now you can perform storage functions, such as the one below
        //('client_id', 'client_secret', 'redirect_uri', 'grant_types', 'scope', 'user_id')
        //$storage->setClientDetails("testclient", "testpass", "http://media.test.dev", "client_credentials", "http://media.test.dev/");

        $server = new \OAuth2\Server($storage, array('enforce_state'=>false));
        $server->addGrantType(new \OAuth2\GrantType\ClientCredentials($storage));
        $server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($storage));
        $this->_server = $server;
        return true;
    }

    /**
     * curl -u testclient:testpass http://media.test.dev/oauth2/token -d 'grant_type=client_credentials'
     * 
     * @return json {"access_token":"f6a98820d6f5498ebbd29256931c3f676149879d","expires_in":3600,"token_type":"Bearer","scope":null}
     */
    public function actionToken()
    {
        $this->_server->handleTokenRequest(\OAuth2\Request::createFromGlobals())->send();                
    }

    /**
     * curl http://media.test.dev/oauth2/resource -d 'access_token=f6a98820d6f5498ebbd29256931c3f676149879d'
     * 
     * @return jsonString eg. {"success":true,"message":"You accessed my APIs!"}
     */
    public function actionResource()
    {
        if (!$this->_server->verifyResourceRequest(\OAuth2\Request::createFromGlobals())) {     
            return $this->_server->getResponse()->send();     
        }
        echo json_encode(array('success' => true, 'message' => 'You accessed my APIs!'));
    }

    public function actionAuthorize()
    {
        $request = \OAuth2\Request::createFromGlobals(); 
        $response = new \OAuth2\Response();
        if (!$this->_server->validateAuthorizeRequest($request, $response)) {     
            return $response->send();     
        }
        if (empty($_POST)) {   
            return ' <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>'; 
        }
        $is_authorized = ($_POST['authorized'] === 'yes'); 

        $this->_server->handleAuthorizeRequest($request, $response, $is_authorized); 
        if ($is_authorized) {
            $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40);   
            //exit("SUCCESS! Authorization Code: $code"); 
        } 
        return $response->send();
    }
}

ClientController.php

<?php
/**
 * Client call RESTful API
 * @copyright Copyright (c) Vastrek
 * 
 */
namespace app\controllers;

use Yii;
use yii\web\Controller;
use yii\authclient\OAuth2;
/**
 * Client call RESTful sample 
 * 
 * @copyright Copyright (c) Vastrek
 * @author Frank <fengxuting@gmail.com>
 * @version  1.0
 * @date 2014-11-13
 */
class ClientController extends Controller{
    public $enableCsrfValidation = false;

    /**
     * 获取token demo
     * @return json 
     */
    public function actionGettoken(){
        $oauthClient = new OAuth2();

        $oauthClient->tokenUrl = "http://media.test.dev/oauth2/token" ;    
        $defaultParams = [
            'client_id' => 'testclient',
            'client_secret' => 'testpass',
            'grant_type' => 'client_credentials',
        ];
        $accessToken = $oauthClient->fetchAccessToken("",$defaultParams) ;
        echo json_encode($accessToken->getParams()) ;
        //echo "token:".$accessToken->getToken() ;
        //echo "<br/>" ;
        //echo "expire:".$accessToken->getExpireDuration() ;
        //TO-DO:token 存储在redis中,且设置过期时间

    }
    /**
     * 模拟form上传图片
     * 
     * @return json success eg.{"status":"y","info":"success","filename":""}
     */
    public function actionUpload(){
        /*
        $access_token = "" ;
        $upload_api = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$access_token}&type=image" ;
        $params = array('media' => '@'.$name,'filename' => $name);
        return uploadByCURL($params,$upload_api) ;    
        */
        //$oauthClient = Yii::app->oauthclent ;

        $upload_api = "http://media.test.dev/media/upload?up" ;
        $temp_name = $_FILES["upfile"]['tmp_name'] ;
        $name = $_FILES['upfile']['name'];        

        $autoThumb = false ;
        if(isset($_POST['autoThumb'])) $autoThumb = $_POST['autoThumb'];
        $category = '' ;
        if(isset($_POST['category'])) $category = $_POST['category'];        
        $thumbArray = false ;
        if(isset($_POST['thumbArray'])) $thumbArray = $_POST['thumbArray'];
        $thumbWH = array() ;
        if(isset($_POST['thumbWH'])) $thumbWH = $_POST['thumbWH'];
        $token = $_POST['access_token'];
        $params = array(
            'upfile' => '@'.$temp_name,
            'access_token' => $token,
            'autoThumb' => $autoThumb,
            'category' => $category,
            'name' => $name,
            'thumbWidth' =>$thumbWidth,
            'thumbHeight' =>$thumbHeight,
            'thumbArray' => $thumbArray,
            'thumbWH' => $thumbWH,            

        );
        return $this->uploadByCURL($params,$upload_api) ;        
    }

    private function uploadByCURL($post_data,$post_url){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $post_url);
        curl_setopt($curl, CURLOPT_POST, true );
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl,CURLOPT_USERAGENT,"Mozilla/4.0");
        $result = curl_exec($curl);
        $error = curl_error($curl);
        return $error ? $error : $result;
    }
}

参考
oauth2-server-php 代码
oauth2-server-php 文档
使用 OAuth2-Server-php 在 Yii 框架上搭建 OAuth2 Server

« 上一篇:osx系统升级macOS 10.12后 | 下一篇:OAuth2 之Nodejs实战»

发表评论 登录

Top