请大神指导一下 yii2 的 oauth2 什么玩 [ 2.0 版本 ]
请问哪一位大侠 玩过 yii2 的 oauth2
### php composer.phar require --prefer-dist bshaffer/oauth2-server-php "*"
这个都安装好了,表也已经建立好。
然后改怎么玩,请大神指导!(才接触oauth2,好难!不是很懂)
共 8 个回答
-
请点击下面的链接
YII2 Auth2.0与QQ第三方登录共 3 条回复http://www.kuitao8.com/20150919/4061.shtml
这个里面有一些,基本能能用,但是还是不够用,但是没有把yii2的Oauth2-server的功能好好的利用上。
请大神们能帮帮忙!刚才发错了链接,是这个: http://www.easypao.com/post/21
-
6o,老大正要弄个这种东西
共 11 条回复http://bshaffer.github.io/oauth2-server-php-docs/cookbook/
这个东西不错。应该在里面能找到答案,加油吧!@liuruiaaa 我早上也帮他找了这个,哈哈,所以说6
@liuruiaaa 那你知道 https://github.com/Filsh/yii2-oauth2-server 这个怎么用吗?这是人家写的yii的版本,不过我看不太懂,看得懂教我。。
<?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; }
}
<?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!'))
- 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; }
}
'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上的有点不一样。
照着 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
//执行成功后再删除掉这方法以下网站可供参考,讲的都不错:
http://blog.csdn.net/alonesword/article/details/12190075
http://www.cnblogs.com/txw1958/archive/2013/01/19/2867584.html
http://open.weibo.com/wiki/Oauth2/authorize
http://bshaffer.github.io/oauth2-server-php-docs/cookbook/ 这个不错,配上网页翻译,很好!
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
http://blog.csdn.net/newjueqi/article/details/39501053@liuruiaaa 好的,我去看看
@liuruiaaa
primaryKey($columns = NULL) -
测试的时候报这个错误,有解答的吗
`{"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 条回复`
'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, ], ], ],
`
@wjj891201 yii2 --2.0.13以后getRequest()逻辑有修改导致
-
heroman120 回答于 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
最后登录:2017-07-14
在线时长:10小时53分
- 粉丝6
- 金钱163
- 威望10
- 积分363