* @copyright Copyright © WEBZING 2013- * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version 1.0.0 */ namespace app\components\OpenAuth; use app\common\components\SiteUrl; use app\common\helpers\Identify; use app\common\helpers\Session; use app\components\WeiXin\WeiXin; use app\modules\ucenter\models\UserOpenAuth; use Yii; class OpenAuth extends \yii\base\Component { public $weibo; public $wx; public $qq; public $dd; public $mp; public $method; public $app; private $wbAppId; private $wbAppSecret; public $wbScope; public $wbCallBackUrl; private $wxAppId; private $wxAppSecret; public $wxCallBackUrl; private $qqAppId; private $qqAppKey; public $qqScope; public $qqCallBackUrl; private $mpAppId; private $mpAppSecret; private $mpToken; private $dingtalkAppKey; private $dingtalkAppSecret; public $dingtalkCallBackUrl; public $apps = array('weibo','wx','qq','dd','mp'); public function __construct() { $this->qqScope = 'get_user_info,add_share,list_album,add_album,upload_pic,add_topic,add_one_blog,add_weibo,check_page_fans,add_t,add_pic_t,del_t,get_repost_list,get_info,get_other_info,get_fanslist,get_idolist,add_idol,del_idol,get_tenpay_addr'; $this->wbScope = ''; $keys = array('wbAppId','wbAppSecret','wbCallBackUrl','wxAppId','wxAppSecret','wxCallBackUrl','qqAppId','qqAppKey','qqCallBackUrl','dingtalkAppKey','dingtalkAppSecret','dingtalkCallBackUrl','mpAppId','mpAppSecret','mpToken','openWbLogin','openWxLogin','openQqLogin','openMpLogin','mpAutoLoginWap','openMpSubLogin','dingtalkLogin'); foreach($keys as $key) { if(is_wap_site()) { $tempArgs[$key] = in_array($key,array('mpAppId','mpAppSecret','mpToken','openMpLogin','mpAutoLoginWap','openMpSubLogin'))?Yii::$app->params['openauth'][$key]:Yii::$app->params['openauth']['m_'.$key]; } else { $tempArgs[$key] = Yii::$app->params['openauth'][$key]; } $tempArgs[$key] = $tempArgs[$key]? $tempArgs[$key]:''; } if(isset($tempArgs))$args = $tempArgs; extract($args); if(isset($wbAppId)&&!defined('WB_APPID')) define("WB_APPID", $wbAppId); if(isset($wbAppSecret)&&!defined('WB_APPSECRET')) define("WB_APPSECRET", $wbAppSecret); if(empty($wbScope))$wbScope = $this->wbScope; if(isset($wbScope)&&!defined('WB_SCOPE')) define("WB_SCOPE", $wbScope); if(isset($wbCallBackUrl)) $this->wbCallBackUrl = $wbCallBackUrl; if(isset($wxAppId)&&!defined('WX_APPID')) define("WX_APPID", $wxAppId); if(isset($wxAppSecret)&&!defined('WX_APPSECRET')) define("WX_APPSECRET", $wxAppSecret); if(isset($wxCallBackUrl)) $this->wxCallBackUrl = $wxCallBackUrl; if(isset($qqAppId)&&!defined('QQ_APPID')) define("QQ_APPID", $qqAppId); if(isset($qqAppKey)&&!defined('QQ_APPKEY')) define("QQ_APPKEY", $qqAppKey); if(empty($qqScope))$qqScope = $this->qqScope; if(isset($qqScope)&&!defined('QQ_SCOPE')) define("QQ_SCOPE", $qqScope); if(isset($qqCallBackUrl)) $this->qqCallBackUrl = $qqCallBackUrl; if(isset($dingtalkAppKey)&&!defined('DD_APPKEY')) define("DD_APPKEY", $dingtalkAppKey); if(isset($dingtalkAppSecret)&&!defined('DD_APPSECRET')) define("DD_APPSECRET", $dingtalkAppSecret); if(isset($dingtalkCallBackUrl)) $this->dingtalkCallBackUrl = $dingtalkCallBackUrl; if(isset($mpAppId)&&!defined('MP_APPID')) define("MP_APPID", $mpAppId); if(isset($mpAppSecret)&&!defined('MP_APPSECRET')) define("MP_APPSECRET", $mpAppSecret); if(isset($mpToken)&&!defined('MP_TOKEN')) define("MP_TOKEN", $mpToken); $this->weibo = new \app\components\OpenAuth\core\weibo(); $this->qq = new \app\components\OpenAuth\core\qq(); $this->wx = new \app\components\OpenAuth\core\wx(); $this->dd = new \app\components\OpenAuth\core\dd(); Session::set('app',[]); } public function init() { parent::init(); } //获取微信授权链接 public function getWxLoginUrl() { $state = uniqid('wx_', true); $url = $this->wx->codeUrl($this->wxCallBackUrl,$state); Session::set('wx_state',$state); return $url; } //微信验证 public function wxAuth() { $state = $_REQUEST['state']; $code = $_REQUEST['code']; if (Session::get('wx_state')==null || $state !== Session::get('wx_state')) exit("参数错误!请返回重新使用微信登录!"); $token = $this->wx->getAccessToken($code); if (isset($token['errcode'])) { exit("验证错误!请返回重新使用微信登录!"); } Session::set('wx_token',array('access_token' => $token['access_token'], 'openid' => $token['openid'], 'uid' => $token['openid'], 'expires_in' => $token['expires_in'])); $this->_callback('wx'); return true; } //获取QQ授权链接地址 public function getQqLoginUrl() { $state = uniqid('qq_', true); $url = $this->qq->getAuthorizeURL($this->qqCallBackUrl, 'code', $state, $this->qqScope); Session::set('qq_state',$state); return $url; } //QQ授权验证 public function qqAuth() { $state = $_REQUEST['state']; $code = $_REQUEST['code']; if (Session::get('qq_state')==null || $state !== Session::get('qq_state')) exit("参数错误!请返回重新使用QQ登录!"); $keys = array('code' => $code, 'redirect_uri' => $this->qqCallBackUrl); $token = $this->qq->getAccessToken('code', $keys); if (isset($token['error'])) exit("验证错误!请返回重新使用QQ登录!"); Session::set('qq_token',$token); $openid = $this->qq->getOpenID(); Session::set('qq_token',array('access_token' => $token['access_token'], 'openid' => $openid, 'uid' => $openid, 'expires_in' => $token['expires_in'])); $this->_callback('qq'); return true; } //获取微博授权链接地址 public function getWbLoginUrl() { $state = uniqid('weibo_', true); $url = $this->weibo->getAuthorizeURL($this->wbCallBackUrl, 'code', $state); Session::set('weibo_state',$state); return $url; } //微博授权验证 public function wbAuth() { $state = $_REQUEST['state']; $code = $_REQUEST['code']; if (Session::get('weibo_state')==null || $state !== Session::get('weibo_state')) exit("参数错误!请返回重新使用新浪微博登录!"); $keys = array('code' => $code, 'redirect_uri' => $this->wbCallBackUrl); $token = $this->weibo->getAccessToken('code', $keys); if (isset($token['error'])) exit("验证错误!请返回重新使用新浪微博登录!"); Session::set('weibo_token',$token); $this->_callback('weibo'); return true; } //获取钉钉授权链接 public function getDdLoginUrl() { $state = uniqid('dd_', true); $url = $this->dd->authUrl($this->dingtalkCallBackUrl,$state); Session::set('dd_state',$state); return $url; } //钉钉验证 public function ddAuth() { $state = $_REQUEST['state']; $code = $_REQUEST['authCode']; if (Session::get('dd_state')==null || $state !== Session::get('dd_state')) exit("参数错误!请返回重新使用钉钉登录!"); $token = $this->dd->getAccessToken($code); if (isset($token['errcode'])) { exit("验证错误!请返回重新使用钉钉登录!"); } Session::set('dd_token',array('access_token' => $token['access_token'], 'expires_in' => $token['expires_in'], 'refresh_token' => $token['refresh_token'])); return true; } //生成登录公众号二维码 public function mpLogin() { $scene_id = mt_rand(100000000,999999999).rand(0,9).rand(0,9); if(Yii::$app->params['openauth']['openMpSubLogin']&&!IN_WAP) { $args = array( 'appId'=>MP_APPID, 'appSecret'=>MP_APPSECRET, 'token'=>MP_TOKEN, ); $weixin = new WeiXin($args); $weixin->init(); $scene_id = 'mplogin_'.$scene_id; $result = $weixin->createQrcode($scene_id,3); $returnResult = [ 'error' => 0, 'msg' => '请求成功', 'data' => ['codeUrl'=>$result['codeUrl'],'scene_id'=>$scene_id,'expire'=>Yii::$app->params['qrcodeExpire']], 'code'=>200 ]; echo_json($returnResult); } else { //通过进入H5微信授权登录 $expireTime = TIMESTAMP-30*60; UserOpenAuth::deleteAll("app_uid='0' and app='mp' and bind_time<$expireTime"); $openAuth = new UserOpenAuth(); $openAuth->app = 'mp'; $openAuth->app_uid = '0'; $openAuth->scene_id = (defined('IN_WAP')&&IN_WAP==TRUE)?'wap_'.$scene_id:'pc_'.$scene_id; $openAuth->app_unionid = ''; $openAuth->app_unionname = 'wx'; $openAuth->bind_time = TIMESTAMP; $openAuth->share_no = \app\common\helpers\Cookie::getCookie(Yii::$app->params['shareArgName'])? \app\common\helpers\Cookie::getCookie(Yii::$app->params['shareArgName']):''; $openAuth->hash = ''; if($openAuth->save()) { //如果仅仅绑定,应该传个标识符到手机端 if(Identify::hasLogined())$uauth = sys_auth(Identify::getUserInfo(NULL,'user_id')); $url = (defined('IN_WAP')&&IN_WAP==TRUE)?SiteUrl::mpLogin($scene_id,1):(Identify::hasLogined()?SiteUrl::mpLogin($scene_id,0,$uauth):SiteUrl::mpLogin($scene_id)); $url = str_replace(WEB_URL,WAP_URL,$url); $codeUrl =APP_URL.'ajax/qrcode/?url='.urlencode($url); $returnResult = [ 'error' => 0, 'msg' => '请求成功', 'data' => ['codeUrl'=>$codeUrl,'scene_id'=>$scene_id,'expire'=>Yii::$app->params['qrcodeExpire'],'url'=>$url], 'code'=>200 ]; if(defined('IN_WAP')&&IN_WAP==TRUE) { return $returnResult; } else { echo_json($returnResult); } } } } /** * 获取指定应用的用户UID * @param string $app 应用名称 weibo/qq 默认qq * @return mixed */ function getAppUserId($app = 'qq') { $uid = 0; if ($app == 'weibo') { $uid = Session::get('weibo_token.uid')? Session::get('weibo_token.uid'): 0; } else if ($app == 'qq') { $uid = Session::get('qq_token.uid')? Session::get('qq_token.uid'): 0; } else if ($app == 'wx') { $uid =Session::get('wx_token.uid')? Session::get('wx_token.uid'): 0; } return $uid; } /** * 判断应用是否已经登录 * @param string $app 应用名称 weibo/qq qq * @return bool */ function checkAppLogin($app = 'qq') { if (!in_array($app, $this->apps)) return false; return $this->$app->verify() ? true : false; } /** * 退出/注销 */ public function logout() { $app = isset($_GET['app']) ? $_GET['app'] : ''; if (in_array($app,$this->apps)) { Session::set('app.'.$app,''); Session::set("{$app}_token",''); } } /** * 获取应用的中文名称 * @param string $app /weibo/qq 默认renren * @return string */ function getAppName($app = 'qq') { $app_array = array( 'weibo' => '新浪微博', 'qq' => '腾讯QQ', 'wx' => '微信', 'dd' => '钉钉', 'mp' => '微信公众号'); $app_name = isset($app_array[$app]) ? $app_array[$app] : ''; return $app_name; } //验证成功后的处理跳转地址 private function _callback($app) { if (in_array($app,$this->apps)) { //todo } } /** * 获取指定应用的用户信息 * @param string $app 应用名称 renren/weibo/qq 默认renren * @return mixed */ public function getAppUserInfo($app = 'qq') { $result = array(); if ($app == 'weibo') { $weiboclient = new \app\components\OpenAuth\core\Weiboclient(Session::get('weibo_token.access_token')); $result = $weiboclient->show_user_by_id(Session::get('weibo_token.uid')); $result['name'] = $result['name']; $result['nick_name'] = $result['screen_name']; $result['uid'] = Session::get('weibo_token.uid'); unset($result['id']); $result['avatar'] = $result['profile_image_url']; $result['unionid'] = Session::get('weibo_token.uid'); $result['sex'] = $result['gender'] == 'm' ? 1: 2; $result['birthday'] = ''; } else if ($app == 'qq') { $qqclient = new \app\components\OpenAuth\core\qqclient(Session::get('qq_token.access_token'), Session::get('qq_token.openid')); $result = $qqclient->get_user_info(); $result['name'] = $result['nickname']; $result['nick_name'] = $result['nickname']; $result['uid'] = Session::get('qq_token.openid'); $result['avatar'] = $result['figureurl_qq_2']?$result['figureurl_qq_2']:$result['figureurl_qq_1']; $result['unionid'] = Session::get('qq_token.openid'); $result['sex'] = $result['gender']=='男'?1:2; $result['birthday'] = ''; }else if ($app == 'wx') { $wxclient = new \app\components\OpenAuth\core\wxclient(); $result = $wxclient->get_user_info(); $result = json_decode($result[0],true); $result['name'] = $result['nickname']; $result['nick_name'] = $result['nickname']; $result['uid'] = Session::get('wx_token.openid'); $result['avatar'] = $result['headimgurl']; $result['unionid'] = $result['unionid']; $result['sex'] = $result['sex']; $result['birthday'] = ''; } else if ($app == 'dd') { $ddclient = new \app\components\OpenAuth\core\ddclient(Session::get('dd_token.access_token')); $result = $ddclient->get_user_info(); $result = json_decode($result,true); $result['name'] = $result['nick']; $result['nick_name'] = $result['nick']; $result['uid'] = $result['openId']; $result['unionid'] = $result['unionId']; $result['avatar'] = $result['avatarUrl']; $result['mobile'] = $result['mobile']; } return $result; } //生成开启接收微信消息通知二维码 public function mpMsg() { $scene_id = mt_rand(100000000,999999999).rand(0,9).rand(0,9); if(Yii::$app->params['mp']['openmsg']) { $args = array( 'appId'=>Yii::$app->params['mp']['mpAppId'], 'appSecret'=>Yii::$app->params['mp']['mpAppSecret'], 'token'=>Yii::$app->params['mp']['mpToken'], ); $weixin = new WeiXin($args); $weixin->init(); $scene_id = 'mpmsg_'.$scene_id; $result = $weixin->createQrcode($scene_id,3); $returnResult= ([ 'error' => 0, 'msg' => '请求成功', 'data' => ['codeUrl'=>$result['codeUrl'],'scene_id'=>$scene_id,'expire'=>Yii::$app->params['qrcodeExpire']], 'code'=>200 ]); if(defined('IN_WAP')&&IN_WAP==TRUE) { $expireTime = TIMESTAMP-30*60; UserOpenAuth::deleteAll("app_uid='0' and app='mpmsg' and bind_time<$expireTime"); $openAuth = new UserOpenAuth(); $openAuth->app = 'mpmsg'; $openAuth->app_uid = '0'; $openAuth->scene_id = $scene_id; $openAuth->app_unionid = ''; $openAuth->app_unionname = 'mpmsg'; $openAuth->bind_time = TIMESTAMP; $openAuth->save(); return $returnResult; } else { echo_json($returnResult); } } } //生成关注公众号二维码 public function mpSub() { $scene_id = mt_rand(100000000,999999999).rand(0,9).rand(0,9); if(Yii::$app->params['mp']['mpAppId']) { $args = array( 'appId'=>Yii::$app->params['mp']['mpAppId'], 'appSecret'=>Yii::$app->params['mp']['mpAppSecret'], 'token'=>Yii::$app->params['mp']['mpToken'], ); $weixin = new WeiXin($args); $weixin->init(); $scene_id = 'mpsub_'.$scene_id; $result = $weixin->createQrcode($scene_id,3); if($result['codeUrl']) { ob_clean(); echo https_request($result['codeUrl']); } } } //生成下载文档二维码 public function freeDowncode() { $id = Yii::$app->request->get('id'); if(!empty($id)) { if(Yii::$app->params['mp']['mpAppId']) { $args = array( 'appId'=>Yii::$app->params['mp']['mpAppId'], 'appSecret'=>Yii::$app->params['mp']['mpAppSecret'], 'token'=>Yii::$app->params['mp']['mpToken'], ); $weixin = new WeiXin($args); $weixin->init(); $scene_id ='freedowndoc_'.$id; $result = $weixin->createQrcode($scene_id,3); echo_json([ 'error' => 0, 'msg' => '请求成功', 'data' => ['codeUrl'=>$result['codeUrl'],'scene_id'=>$scene_id], 'code'=>200 ]); } } } }