给phpwind加自定义oauth认证(第三方)
由于业务系统使用keycloak做统一的认证,但论坛直接使用的phpwind。
用两套用户体系确实有点不太合适,特别是国情决定的实名制等。
如果在APP上搞定了用户注册加实名的话,那论坛使用APP的用户进行登录,理论上也是实现实名了。
代码是基于phpwind v9.1.0
,基础上的。
大概改不到10个文件,下面按照先后顺序依次说明。
1.开放平台接入设置
//ThirdOpenPlatformController.php 文件,可能会有两个 /** * 显示在模板中的文本内容 * * @access private * @return void */ private function _displayText($type){ $_lab1 = array( 'AppId' =>'AppKey', 'AppKey'=>'AppSecret', ); $_lab2 = array( 'AppId' =>'AppId', 'AppKey'=>'AppKey', ); $_labs = array( 'taobao'=>$_lab1, 'weibo' =>$_lab1, 'weixin'=>$_lab2, 'qq' =>$_lab2, 'hifipi'=> $_lab2, //追加 ); return $_labs[$type]; }
2.Windid工具库
//WindidUtility.php 追加$htoken的处理,用于通过header['Authorization']传值, public static function buildRequest($url, $params = array(), $isreturn = true, $timeout = 10, $method = 'post', $htoken = '') { $request = Wind::getComponent('httptransfer', array($url, $timeout)); $request->setWaitResponse($isreturn); if ($htoken != '') { $request->setHeader($htoken, 'Authorization'); } if ($method == 'post') { if (!$params) $params = array('__data' => '1');//兼容部分版本post content不能为空的错误 return $request->post($params); } else { return $request->get($params); } }
3.登录
//PwThirdLoginService.php 追加针对oauth2认证的逻辑 // 追加hifipi的相关keycloak定义 public static $supportedPlatforms = array( // See http://wiki.open.qq.com/wiki/website/%E4%BD%BF%E7%94%A8Authorization_Code%E8%8E%B7%E5%8F%96Access_Token 'qq' => array( 'img' => 'http://oss.aliyuncs.com/phpwind-image/4819ac3d87071089648af06c5fb7f204.png', 'authorize' => 'https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&state=phpwind&scope=get_user_info', 'accesstoken' => 'https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s', 'openid' => 'https://graph.qq.com/oauth2.0/me?access_token=%s', 'userinfo' => 'https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s', 'text' => '使用QQ帐号登录', ), // See http://open.weibo.com/wiki/%E9%A6%96%E9%A1%B5 'weibo' => array( 'img' => 'http://oss.aliyuncs.com/phpwind-image/be7945e0d9521e74b8130a138b8694df.png', 'authorize' => 'https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&scope=email&state=phpwind&display=default', 'accesstoken' => 'https://api.weibo.com/oauth2/access_token', 'userinfo' => 'https://api.weibo.com/2/users/show.json?access_token=%s&uid=%s', 'text' => '使用新浪微博帐号登录', ), 'hifipi'=>array( 'img' => 'http://auth.hifipi.com/auth/resources/3.3.0.final/admin/keycloak/img/keyclok-logo.png', 'authorize' => 'http://auth.hifipi.com/auth/realms/hifipi/protocol/openid-connect/auth?response_type=code&client_id=%s&redirect_uri=%s&state=phpwind&scope=get_user_info', 'accesstoken' => 'http://auth.hifipi.com/auth/realms/hifipi/protocol/openid-connect/token', 'userinfo' => 'http://auth.hifipi.com/auth/realms/hifipi/protocol/openid-connect/userinfo', 'text' => '使用HIFIPI帐号登录', ), );
// 追加hifipi的auth处理 public function getAuthorizeUrl($platform) { $thirdPlatforms = Wekit::C('webThirdLogin'); $config = Wekit::C()->getConfigByName('site', 'info.url'); $redirecturl = $config['value'].'/index.php?m=u&c=login&a=thirdlogincallback&platform='.$platform; switch($platform) { case 'qq': return sprintf(self::$supportedPlatforms[$platform]['authorize'], $thirdPlatforms[$platform.'.appid'], urlencode($redirecturl) ); case 'weibo': return sprintf(self::$supportedPlatforms[$platform]['authorize'], $thirdPlatforms[$platform.'.appid'], urlencode($redirecturl) ); case 'hifipi': return sprintf(self::$supportedPlatforms[$platform]['authorize'], $thirdPlatforms[$platform.'.appid'], urlencode($redirecturl) ); default: // should never happen return ''; } }
//追加hifipi的token处理,取到access_token就完事了 public function getAccessToken($platform, $authcode) { $thirdPlatforms = Wekit::C('webThirdLogin'); $config = Wekit::C()->getConfigByName('site', 'info.url'); $method = 'get'; $redirecturl = $config['value'].'/index.php?m=u&c=login&a=thirdlogincallback&platform='.$platform; switch($platform) { case 'qq': $url = sprintf(self::$supportedPlatforms[$platform]['accesstoken'], $thirdPlatforms[$platform.'.appid'], $thirdPlatforms[$platform.'.appkey'], $authcode, urlencode($redirecturl) ); break; case 'weibo': $url = self::$supportedPlatforms[$platform]['accesstoken']; $postdata = array('client_id' => $thirdPlatforms[$platform.'.appid'], 'client_secret' => $thirdPlatforms[$platform.'.appkey'], 'code' => $authcode, 'redirect_uri' => $redirecturl, ); $method = 'post'; break; case 'hifipi': $url = self::$supportedPlatforms[$platform]['accesstoken']; $postdata = array('client_id' => $thirdPlatforms[$platform.'.appid'], 'grant_type' => 'authorization_code', 'client_secret' => $thirdPlatforms[$platform.'.appkey'], 'code' => $authcode, 'redirect_uri' => $redirecturl, ); $method = 'post'; break; default: // should never happen return array(false, ''); } $data = $this->_request($url, ($method == 'post' ? $postdata : array()), $method); if (!$data) { return array(false, ''); } switch($platform) { case 'qq': if (substr($data, 0, 8) == 'callback') { $result = json_decode(substr($data, 10, -4), true); } else { parse_str($data, $result); } if (isset($result['error'])) { return array(false, array($result['error'], $result['error_description'])); } else { return array(true, $result['access_token'], 'extra' => array()); } case 'weibo': $result = json_decode($data, true); if (isset($result['error_code']) && $result['error_code'] != 0) { return array(false, array($result['error_code'], $result['error'])); } return array(true, $result['access_token'], 'extra' => array('uid' => $result['uid'])); case 'hifipi': $result = json_decode($data, true); if (isset($result['error']) && $result['error'] != 0) { return array(false, array($result['error'], $result['error_description'])); } return array(true, $result['access_token'], 'extra' => array('uid' => $result['uid'])); default: return array(false, ''); } }
//取用户info,由于原代码有点长,这里省略了部分 public function getUserInfo($platform, $accesstoken, array $extra) { switch($platform) { case 'qq': $url = sprintf(self::$supportedPlatforms[$platform]['openid'], $accesstoken ); break; default: break; } if (isset($url)) { $openid = $this->getOpenId($url); if (!$openid[0]) { return $openid; } $openid = $openid[1]; } else { $openid = $extra['uid']; } $htoken = ''; //追加 $thirdPlatforms = Wekit::C('webThirdLogin'); switch($platform) { case 'qq': /////此处省略部分代码 case 'weibo': /////此处省略部分代码 case 'hifipi': $url = self::$supportedPlatforms[$platform]['userinfo']; $htoken = 'bearer '.$accesstoken; //追加 break; default: break; } $data = $this->_request($url, array(), 'get', $htoken); $userinfo = array(); switch($platform) { case 'qq': /////此处省略部分代码 case 'weibo': /////此处省略部分代码 case 'hifipi': $result = json_decode($data, true); if (isset($result['error']) && $result['error'] != 0) { $userinfo[0] = false; $userinfo[1] = array('code' => $result['error'], 'msg' => $result['error_description'] ); } else { $userinfo[0] = true; $userinfo[1] = array( 'uid' => $result['sub'], 'username' => substr($result['preferred_username'], 0, 15), //'gender' => $result['gender'] == 'm' ? 0 : 1, //'avatar' => $result['avatar_large'], 'type' => $platform, 'email' => $result['email'], ); } return $userinfo; default: return array(false, ''); } }
//追加了$htoken的参数 protected function _request($url, $params, $method = 'get', $htoken = '') { $result = WindidUtility::buildRequest($url, $params, /* isreturn = */ true, self::HTTP_TIMEOUT, $method, $htoken); return !empty($result) ? $result : false; }
4.管理后台的画面
.....省略..... //thirdopenplatform_run.htm <ul class="cc"> <li {$typeClasses['qq']|html}><a href="{@url:config/ThirdOpenPlatform/run?type=qq}">QQ</a></li> <li {$typeClasses['weibo']|html}><a href="{@url:config/ThirdOpenPlatform/run?type=weibo}">新浪微博</a></li> <li {$typeClasses['hifipi']|html}><a href="{@url:config/ThirdOpenPlatform/run?type=hifipi}">Keycloak</a></li> </ul> .....省略.....
在后台及keycloak里配置好realm和client_id/client_secret,然后就可以使用keycloak的账号进行登录了。
具体效果,可以参考http://bbs.hifipi.com,刚建起来现在是测试(现在是连的测试用keycloak服务器),APP正在着手开发中。
相关推荐
86417413 2020-11-25
83206733 2020-11-19
86276537 2020-11-19
83266337 2020-11-19
86256434 2020-11-17
zhouboxiao 2020-11-16
rise 2020-11-22
sssdssxss 2020-11-20
windle 2020-11-10
孙雪峰 2020-10-30
85477104 2020-11-17
xfcyhades 2020-11-20
liuxudong00 2020-11-19
cheidou 2020-11-19
gunhunti 2020-09-25
csdnYF 2020-11-15
达观数据 2020-11-11
playlinuxxx 2020-11-11