2016-05-13 10:02:57 13368次浏览 8条回答 6 悬赏 10 金钱

请问哪一位大侠 玩过 yii2 的 oauth2

### php composer.phar require --prefer-dist bshaffer/oauth2-server-php "*" 

这个都安装好了,表也已经建立好。
然后改怎么玩,请大神指导!(才接触oauth2,好难!不是很懂)

  • 回答于 2016-05-13 11:13 举报

    请点击下面的链接
    YII2 Auth2.0与QQ第三方登录

    3 条回复
    回复于 2016-05-13 12:36 回复

    大哥不是这样的,是自己做个oauth2 server 不是去用其它平台的第三方登陆。是自己做个第三方登录,然后让其它平台来使用。

    回复于 2016-05-13 12:39 回复

    http://www.kuitao8.com/20150919/4061.shtml
    这个里面有一些,基本能能用,但是还是不够用,但是没有把yii2的Oauth2-server的功能好好的利用上。
    请大神们能帮帮忙!

    回复于 2016-05-13 12:40 回复

    刚才发错了链接,是这个: http://www.easypao.com/post/21

  • 回答于 2016-05-13 13:45 举报

    6o,老大正要弄个这种东西

    11 条回复
    回复于 2016-05-13 14:02 回复

    http://bshaffer.github.io/oauth2-server-php-docs/cookbook/
    这个东西不错。应该在里面能找到答案,加油吧!

    回复于 2016-05-13 14:05 回复

    我早上也帮他找了这个,哈哈,所以说6

    回复于 2016-05-20 16:45 回复

    那你知道 https://github.com/Filsh/yii2-oauth2-server 这个怎么用吗?这是人家写的yii的版本,不过我看不太懂,看得懂教我。。

    回复于 2016-05-26 10:43 回复

    <?php
    namespace appinterface\controllers;

    use Yii;
    use yii\web\Controller;

    /**

    • 模拟客户端 在hosts里面把这个配好:http://appinterface.com 客户端和服务器端都放在controllers 同一个文件夹下面的。
      */
      class TestoauthController extends Controller {

      private $tokenuri="http://appinterface.com/oauth/token"; //请求token的url 可以获取token 、通过codke获取token 、获取refretoken
      private $client_id = 'testclient';
      private $passwd = 'testpass';
      private $redirect = 'http://localhost';//用来验证的
      private $redirect2 = 'http://appinterface.com/testoauth/getcode';//用来成功后跳转的 应该和上面的$redirect 一样

      public function actionIndex()
      {

       $this->layout = false;
       return $this->render('index');
      

      }
      public function actionSendoauth()
      {

       $token = $this->actionTest1();
       $token = $token['access_token'];
       $url = "http://appinterface.com/oauth/authorize?client_id=".$this->client_id."&response_type=code&redirect_uri=".$this->redirect."&access_token=".$token."&redirect_uri2=".$this->redirect2;
       header("Location:".$url);
       exit;
      

      }

      public function actionGetcode(){

        $arr = $this->actionTest3();
        $arr[] = '以后每次调用我们的资源都会对access_token 验证他的合法性,过期时间是1个小时,refresh_token没有过期,期限是10天左右。';
        $arr[] = '请储存好您的 access_token 和 refresh_token ,access_token过期后 可以用refresh_token 获取access_token ';
        $arr[] = '需要再次获取token和refrentoken可以访问:http://appinterface.com/testoauth/getrefretoken?refresh_token=您储存的refresh_token';
        echo '<pre>';
        print_r($arr);
      

      }

      public function actionGetrefretoken(){

       $arr = $this->actionRefresh();
       print_r($arr);
      

      }

      //curl -u testclient:testpass http://localhost/yiitest/advanced/frontend/web/index.php?r=oauth/token -d "grant_type=password&username=rereadyou&password=111111"
      //这条成功了的
      // 模拟这一条 curl -u testclient:testpass http://localhost/yiitest/advanced/frontend/web/index.php?r=oauth/token -d grant_type=client_credentials

      /**

      • 获取未被验证的 token
      • @return type
        */
        public function actionTest1(){

        $data = array('grant_type' => 'client_credentials','redirect_uri'=>$this->redirect);
        $userpasswd = $this->client_id.':'.$this->passwd;
        $return = $this->curlpost($this->tokenuri,$data,$userpasswd);
        $return = json_decode($return,true);
        return $return;
        }

      /**

      • 重新获取refresh_token与token
      • @return type
        */
        public function actionRefresh(){
        $request = Yii::$app->request;
        $data = array('grant_type' => 'refresh_token','refresh_token'=>$request->get('refresh_token'));
        $userpasswd = $this->client_id.':'.$this->passwd;
        $return = $this->curlpost($this->tokenuri,$data,$userpasswd);
        $return = json_decode($return,true);

        return $return;
        

        }

     /**
      * 把用户同意后获得的code拿到token里面去验证 再次获取一个token
      * @return type
      */
      public function actionTest3(){
         $request = Yii::$app->request;
         $data = array('grant_type' => 'authorization_code','code'=>$request->get('code'),'redirect_uri'=>$this->redirect);
         $userpasswd = $this->client_id.':'.$this->passwd;
         $return = $this->curlpost($this->tokenuri,$data,$userpasswd);
         $return = json_decode($return,true);
         return $return;
      }
     
      
      /**
       * @param type $uri         需要post的url
       * @param type $data        这个url需要带的参数
       * @param type $userpasswd  用户名密码
       * @return type             返回返回的数据       
       */
    public function curlpost($uri,$data,$userpasswd=null){
        
        $ch = curl_init ();
        curl_setopt ( $ch, CURLOPT_URL, $uri );
        curl_setopt ( $ch, CURLOPT_POST, 1 );
        curl_setopt ( $ch, CURLOPT_HEADER, 0 );
        if($userpasswd!=null){
          curl_setopt ( $ch, CURLOPT_USERPWD, $userpasswd);
        }
        curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
        curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data );
        $return = curl_exec ( $ch );
        curl_close ( $ch );
        return  $return;
        
    }
    
    

    }

    回复于 2016-05-26 10:46 回复

    <?php

    namespace appinterface\controllers;
    use Yii;
    use yii\web\Controller;
    use common\models\Member;
    use common\helpers\BaseHelper;
    /* 模拟服务器端

    http://appinterface.com/testoauth/test1 获取未授权的 token

    • 首先客户端 引导客户点击个链接,在过程中 获取未授权的 token,然后把这token发送给我们的服务器,然后页面跳转在我们的服务起的页面上
    • 这个主要是用的 oauth_clients表 里面的内容 ,字段:client_id 账号,client_secret 密码,
    • redirect_uri 回调url(在下面注释第三个接口上,要匹配) ,grant_types 权限 里面用空格隔开的 ,scope与user_id没发现有什么用
    • 这oauth_clients表应该弄成可以让第三方自己来注册的表。我们自己后台授权,是否通过。
    • http://appinterface.com/oauth/resource?access_token=f3bae730db475ef363c07a652c82f536f2598427 验证token接口(验证token都可以用这个接口)

    • 这个是验证token(这个token可以是授权的token,也可以是未授权的token )的接口 传参数 access_token
    • 如果用refresh_token 来验证,是通不过的。
    • 成功返回 json_encode(array('success' => true, 'message' => 'You accessed my APIs!'))

    http://appinterface.com/oauth/authorize?client_id=testclient&response_type=code&redirect_uri=http://localhost

    • client_id 是账号 response_type=code 表示用code的验证方式 redirect_uri 在oauth_clients中的字段,一定要写对错了要报错。
      *这个是让用户登陆的验证并且授权的接口 可以直接访问,所以先用上面的 验证token接口 来验证token是否合法,合法后再掉用此接口
    • 我们在这个接口让用户填写,用户名和密码,并选择授权给那个客户端(这个接口里面可以写很多逻辑代码)
    • 如果成功 向客户端服务器返回code,并且跳转到客户端的页面链接。这个链接可以是在我们这边注册就写好了的。
    • http://appinterface.com/testoauth/test3?code=105ebd620e200e058bbbf6c196c366ba312080e4 //参数是上一步的获取的code,要在30秒内用

    • //这是客户端拿到上面返回的 code后 主要获取 token 和 refresh_token两个参数 ,这两个都需要客户端的自己保留存储到数据库
    • 并且每次访问我们的接口,都要用一下这个token,我们判断这个token是否合法,合法就访问资源,
    • 由于我们在 客户端注册的时候,我们是可以为客户端设定权限的,同时用户的登录的时候也是有权限的,
    • 我们可以通过这个两个权限来为客户端调用接口时,设定这个接口的权限。
    • 这一步要在获取code后30秒内执行完。
    • http://appinterface.com/oauth/acc?access_token=e0d41fc96104692b7b4b6517f7b5e6c6ac8b8511

    • 参数是token
    • 返回Array ( [access_token] => d68fd9de7a5f31ac0420eff89b617be190596923 [client_id] => testclient [user_id] => 1 [expires] => 1463453012 [scope] => )
    • 获取用户token的信息 返回user_id、client_id、token之间的关联关系,这个user_id是在 用户点击 授权给那个客户端后做的业务逻辑里面加入的。
    • 方便我们当客户端用token来请求资源的时候,我们知道是哪个用户,和哪个客户端,我们就知道用户的权限和客户端的权限,并返回相应的资源。

    http://appinterface.com/testoauth/refresh?refresh_token=0175114976c91b9320d330d930fd8acf9c027dc9

    • 参数是 refresh_token
    • 一般是用户的token过期后,客户端用refresh_token来掉用此接口,也可以没有过期也掉用此接口。
    • 重新获取token和refresh_token两个参数(并且会自动删除以前的refresh_token), 这两个都需要客户端的自己保留存储到数据库
    • */

    class OauthController extends Controller
    {

    protected $_server;
    public $enableCsrfValidation = false;
    
    public function beforeAction($action)
    {
    
    	if (!parent::beforeAction($action)) return false;
                
    	$db = Yii::$app->db;
    	$dsn      = $db->dsn;
    	$username = $db->username;
    	$password = $db->password;
                $tablePrefix = $db->tablePrefix;
                $charset = $db->charset;
    
    	//ini_set('display_errors',1);
    	//error_reporting(E_ALL);
    	
    	$storage = new \OAuth2\Storage\Pdo(
                        array('dsn' => $dsn, 'username' => $username, 'password' => $password,'options'=>array('tablePrefix'=>$tablePrefix,'charset'=>$charset))
                        ,
                        array(  //这个添加前缀的数组在开始测试的时候建议不要加进去
                        'client_table' => $tablePrefix.'oauth_clients',
                        'access_token_table' => $tablePrefix.'oauth_access_tokens',
                        'refresh_token_table' =>$tablePrefix. 'oauth_refresh_tokens',
                        'code_table' => $tablePrefix.'oauth_authorization_codes',
                        'user_table' => $tablePrefix.'oauth_users',
                        'jwt_table' =>$tablePrefix. 'oauth_jwt',
                        'jti_table' => $tablePrefix.'oauth_jti',
                        'scope_table' =>$tablePrefix. 'oauth_scopes',
                        'public_key_table' => $tablePrefix.'oauth_public_keys',
                         ));
    	$server = new \OAuth2\Server($storage, array('enforce_state'=>false,'id_lifetime'=> 3600,'access_lifetime' => 3600));
    	$server->addGrantType(new \OAuth2\GrantType\ClientCredentials($storage));
    	$server->addGrantType(new \OAuth2\GrantType\AuthorizationCode($storage));
                $server->addGrantType(new \OAuth2\GrantType\RefreshToken($storage,array('always_issue_new_refresh_token' => true, 'unset_refresh_token_after_use' => true)));
                $server->addGrantType(new \OAuth2\GrantType\UserCredentials($storage));
    	$this->_server = $server;
    	return true;
    }
        
    
        // 获取token
    public function actionToken()
    {
    	$this->_server->handleTokenRequest(\OAuth2\Request::createFromGlobals())->send();
    }
    //验证token的正确性
    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!'));
    }
        
        //获取客户端的授权 并获取 code 再拿这个code 去token 方法里面去再次获取token。
        //记到handleAuthorizeRequest()的第4个参数要写进去
        public function actionAuthorize()
    {
                if (!$this->_server->verifyResourceRequest(\OAuth2\Request::createFromGlobals())) { 
                      exit('您的平台的token没有通过验证!');
                }
                
    	$request = \OAuth2\Request::createFromGlobals(); 
    	$response = new \OAuth2\Response();
       
    	if (!$this->_server->validateAuthorizeRequest($request, $response)) {     
    		return $response->send();     
    	}
           
    	if (empty($_POST)) {
    		return ' <form method="post">   
    			
                                        <ul>
                                        <li>用户名:<input type="text" name="username" value=""></li>
                                        <li>密码:<input type="password" name="passwd" value=""></li>
                                        <li><label>您要授权给testclient平台吗?</label></li>
    				<li><input type="submit" name="authorized" value="yes"></li> 
    				<li><input type="submit" name="authorized" value="no"></li>
                                        </ul>
                                        </form>'; 
    	}
                
    	$is_authorized = ($_POST['authorized'] === 'yes'); 
                
    	/*这个里面写业务逻辑*/
    
                $reques = Yii::$app->request;
                $isOk = false;
                
                if ($member = Member::findLogin(BaseHelper::encode($reques->post('username')))){
      
                       if (!empty($reques->post('passwd')) && !empty($member->password_hash) &&Yii::$app->security->validatePassword($reques->post('passwd'), $member->password_hash)) {
                              $isOk = true; 
                        } else {
                              $isOk = false;
                        }
                }else{
                              $isOk = false;
                }
    
                if(!$isOk){
                    exit('您的用户名或密码错误');
                }
                
                /*这个里面写业务逻辑*/
                
                
    	$this->_server->handleAuthorizeRequest($request, $response, $is_authorized,$member->id); 
                //这个$member->id表示的 是member表里面有的userid(为了以后方便自己查找) 这把token与userid绑定到一起。 通过下面的actionAcc()方法可以看出来。
    	if ($is_authorized) {
                        if(strpos('#', $response->getHttpHeader('Location'))!=false){
    		      $code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=')+5, 40); 
                        }else{
                              $code = $response->getHttpHeader('Location');
                        }
                        $arr2 = explode('code=', $code);
                        $this->jumpurl($arr2[1]);//跳转回去
    		//exit("SUCCESS! Authorization Code: $code"); 
    	} 
                
                
                //
    	return $response->send();
    }
    
        /**
         * 获取token绑定的值 user_id 与 client_id
         */
        public  function actionAcc(){ 
    
            $token = $this->_server->getAccessTokenData(\OAuth2\Request::createFromGlobals());
                echo "User ID associated with this token is {$token['user_id']}";
                print_r($token);
        }
        /**
         * 跳转一个url
         */
         public  function jumpurl($code){ 
            $request = Yii::$app->request;
            $redirect_uri = $request->get('redirect_uri2');
            header("Location:".$redirect_uri.'?code='.$code);
            exit;
         }
    
    

    }

    回复于 2016-05-26 10:48 回复

    <?php
    /*那个方法用到的 view页面

    public function actionIndex()
    {    
        $this->layout = false;
        return $this->render('index');
    }
    
    • */
      use yii\helpers\Html;
      ?>

    xxx平台

    <?= Html::a('用我们的平台登录', ['/testoauth/sendoauth'], ['class' => 'btn btn-primary jianquanyi']) ?>

    回复于 2016-05-26 10:51 回复
    'modules' => [
        'oauth2' => [
            'class' => 'filsh\yii2\oauth2server\Module',
            'tokenParamName' => 'accessToken',
            'tokenAccessLifetime' => 3600 * 24,
            'storageMap' => [
                'user_credentials' => 'common\models\Member',
            ],
            'grantTypes' => [
                'user_credentials' => [
                    'class' => 'OAuth2\GrantType\UserCredentials',
                ],
                'refresh_token' => [
                    'class' => 'OAuth2\GrantType\RefreshToken',
                    'always_issue_new_refresh_token' => true
                ]
            ]
        ],
    ], //这个配置与components在同一级别 这点要注意,和readme.md上的有点不一样。
    
    回复于 2016-05-26 10:54 回复

    照着 README.md上面的做 yii migrate --migrationPath=@vendor/filsh/yii2-oauth2-server/migrations
    这地方会报错。

    解决办法 把这个方法

    public function primaryKey($columns) {
        return 'PRIMARY KEY (' . $this->db->getQueryBuilder()->buildColumns($columns) . ')';
    }
    

    //粘贴到 这个里面去 \yii\db\Migration
    //执行成功后再删除掉这方法

    回复于 2016-05-26 11:10 回复

    好的,我去看看

    回复于 2018-07-26 22:22 回复


    primaryKey($columns = NULL)

  • 回答于 2016-05-23 16:12 举报

    mark

  • 回答于 2016-10-14 16:21 举报

    简化模式还要自己写一下,上面没有实现

  • 回答于 2018-03-26 12:02 举报

    客户端模式

  • 回答于 2018-03-26 12:02 举报

    怎么搞哇 老铁

  • 回答于 2018-04-28 10:15 举报

    测试的时候报这个错误,有解答的吗
    `{

    "name": "PHP Recoverable Error",
    "message": "Argument 1 passed to OAuth2\\Server::handleTokenRequest() must be an instance of OAuth2\\RequestInterface, instance of yii\\web\\Request given, called in C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\filsh\\yii2-oauth2-server\\Server.php on line 39 and defined",
    "code": 4096,
    "type": "yii\\base\\ErrorException",
    "file": "C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\bshaffer\\oauth2-server-php\\src\\OAuth2\\Server.php",
    "line": 316,
    "stack-trace": [
        "#0 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\bshaffer\\oauth2-server-php\\src\\OAuth2\\Server.php(316): yii\\base\\ErrorHandler->handleError(4096, 'Argument 1 pass...', 'C:\\\\phpStudy\\\\PHP...', 316, Array)",
        "#1 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\filsh\\yii2-oauth2-server\\Server.php(39): OAuth2\\Server->handleTokenRequest(Object(yii\\web\\Request), NULL)",
        "#2 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\filsh\\yii2-oauth2-server\\controllers\\RestController.php(25): filsh\\yii2\\oauth2server\\Server->handleTokenRequest()",
        "#3 [internal function]: filsh\\yii2\\oauth2server\\controllers\\RestController->actionToken()",
        "#4 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\yiisoft\\yii2\\base\\InlineAction.php(57): call_user_func_array(Array, Array)",
        "#5 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\yiisoft\\yii2\\base\\Controller.php(157): yii\\base\\InlineAction->runWithParams(Array)",
        "#6 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\yiisoft\\yii2\\base\\Module.php(528): yii\\base\\Controller->runAction('token', Array)",
        "#7 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\yiisoft\\yii2\\web\\Application.php(103): yii\\base\\Module->runAction('oauth2/rest/tok...', Array)",
        "#8 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\vendor\\yiisoft\\yii2\\base\\Application.php(386): yii\\web\\Application->handleRequest(Object(yii\\web\\Request))",
        "#9 C:\\phpStudy\\PHPTutorial\\WWW\\oauthtest\\api\\web\\index.php(17): yii\\base\\Application->run()",
        "#10 {main}"
    ]
    

    }`

    4 条回复
    回复于 2018-07-26 22:19 回复

    解决了么?我也是这个问题

    回复于 2018-11-04 22:35 回复

    `
    'oauth2' => [

            'class' => \filsh\yii2\oauth2server\Module::class,
            'tokenParamName' => 'accessToken',
            'tokenAccessLifetime' => 3600 * 24,
            'storageMap' => [
                'user_credentials' => 'common\models\User',
            ],
            'grantTypes' => [
                'user_credentials' => [
                    'class' => 'OAuth2\GrantType\UserCredentials',
                ],
                'refresh_token' => [
                    'class' => 'OAuth2\GrantType\RefreshToken',
                    'always_issue_new_refresh_token' => true
                ]
            ],
            'components' => [
                'request' => function () {
                    return \filsh\yii2\oauth2server\Request::createFromGlobals();
                },
                'response' => [
                    'class' => \filsh\yii2\oauth2server\Response::class,
                ],
            ],
        ],
    

    `

    回复于 2019-03-28 16:13 回复

    为什么啊?能解释一下吗

    回复于 2019-04-11 18:41 回复

    yii2 --2.0.13以后getRequest()逻辑有修改导致

  • 回答于 2018-08-07 14:48 举报

    Exception 'yii\db\Exception' with message 'SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: NO)'
    我再main.php文件中配置好了,配置的不是本地的,是测试服务器的数据库IP和账号密码,是可以访问的,但是使用migrate的./yii migrate --migrationPath=@vendor/filsh/yii2-oauth2-serve./yii migrater/migrations 这个命令时候,访问的时候是本地的,一直报账号密码错误,也找不到migrate的账号密码在哪里配置。 求大神指点。

您需要登录后才可以回答。登录 | 立即注册
liuruiaaa
见习主管

liuruiaaa

注册时间:2016-02-29
最后登录:2017-07-14
在线时长:10小时53分
  • 粉丝6
  • 金钱163
  • 威望10
  • 积分363

热门问题