| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586 | <?php/** * Oauth.php UTF-8 * * * @date    : 2018/4/24 13:39 * * @license 这不是一个自由软件,未经授权不许任何使用和传播。 * @author  : wuyonghong <wyh@huosdk.com> * @version : HUOSDK 8.0 */namespace huo\controller\member;use huo\controller\request\Channel;use huo\controller\request\Device;use huo\controller\request\Game;use huo\controller\request\Mem;use huo\model\member\MemoauthModel;use huolib\constant\FromConst;use huolib\constant\MemConst;use huolib\constant\OauthConst;use huolib\oauth\OAuth as OAuthLib;use huolib\status\MemberStatus;use huolib\tool\StrUtils;use huomp\controller\game\GameMini;use huomp\model\weixin\MpConfModel;use think\Db;use think\Exception;use think\Log;class Oauth extends Member {    protected $domain = MPAPISITE;    protected $oauth_data                      = [            'openid'   => '',/* openid */            'unionid'  => '',/* 用户ID */            'channel'  => '',/* 通道 qq*/            'nickname' => '', /* 昵称 */            'gender'   => '3',/* 性别 */            'avatar'   => ''/* 头像 */        ];    /**     * 获取配置文件     */    public function getOauthConf() {        $_data_wx = [            'type'         => 2,            'app_id'       => '',            'app_secret'   => '',            'redirect_url' => ''        ];        $_rdata[] = $_data_wx;        return $_rdata;    }    /**     * @param string $type 第三方登陆类型     * @param string $from     *     * @param string $url  需要跳转回的地址     *     * @param string $wx_app_id     *     * @return mixed     */    public function getRequestCodeUrl($type, $from = 'pc', $url = '', $wx_app_id = '') {        $_check_type = $this->checkType($type);        if (MemberStatus::NO_ERROR != $_check_type) {            return $this->retErrMsg($_check_type);        }        try {            $_type = $type;            if (FromConst::FROM_WEIXIN != $from && OauthConst::OAUTH_WEIXIN == $type) {                $_type = OauthConst::OAUTH_WXQRCODE;            }            $_config = [];            $_wx_app_secret = (new MpConfModel())->getSecretByMpId($wx_app_id);            if (!empty($_wx_app_secret)) {                $_config['APP_KEY'] = $wx_app_id;                $_config['APP_SECRET'] = $_wx_app_secret;                $_config['CALLBACK'] = '';            }            $_oauth_class = OAuthLib::ins($_type, $_config);            $_back_url = $this->getCallbackUrl($type);            if (!empty($wx_app_id)) {                $_back_url .= '/'.$wx_app_id;            }            $_callback = StrUtils::getUrl($_back_url);            $_callback .= 'back_url='.urlencode($url).'&token='.session_id();            $_oauth_class->setCallback($_callback);            $_oauth_class->setState();            $_url = $_oauth_class->getRequestCodeUrl($from);            $_rdata['url'] = $_url;            return $this->retSucMsg(MemberStatus::NO_ERROR, $_rdata);        } catch (Exception $_e) {            $_err_msg = 'func='.__FUNCTION__.'&class='.__CLASS__.'&type='.$type                        .'&from='.$from.'&url'.$url.'&wx_app_id='.$wx_app_id.'&Exception'                        .$_e->getMessage();            Log::write($_err_msg, Log::ERROR);            return $this->retErrMsg(MemberStatus::UNKNOWN_ERROR);        }    }    /**     * @param $type     *     * @return bool     */    public function checkType($type) {        switch ($type) {            case OauthConst::OAUTH_QQ:            case OauthConst::OAUTH_WEIBO:            case OauthConst::OAUTH_WEIXIN:                return MemberStatus::NO_ERROR;            default:                return MemberStatus::OAUTH_TYPE_ERROR;        }    }    /**     * @param $type     *     * @return string     */    public function getCallbackUrl($type) {        switch ($type) {            case OauthConst::OAUTH_QQ:                $_cb_url = url('sdk/Oauth/callbackQq', '', false, $this->domain);                break;            case OauthConst::OAUTH_WEIBO:                $_cb_url = url('sdk/Oauth/callbackWeibo', '', false, $this->domain);                break;            case OauthConst::OAUTH_WEIXIN:                $_cb_url = url('sdk/Oauth/callbackWeixin', '', false, $this->domain);                break;            default:                $_cb_url = url('sdk/Oauth/callbackWeixin', '', false, $this->domain);        }        return $_cb_url;    }    /**     * 通过code获取登陆信息     *     * @param         $type     * @param         $code     * @param         $from     * @param Game    $game_rq     * @param Channel $channel     * @param Device  $device     * @param Mem     $member     *     * @param array   $_conf     *     * @return array|mixed     */    public function oauthLoginByCode(        $type, $code, $from,        Game $game_rq, Channel $channel, Device $device, Mem $member, $_conf = []    ) {        $_oauth_data = $this->getOauthDataByCode($type, $code, $from, $game_rq->getHAppId(), $_conf);        if (is_numeric($_oauth_data)) {            $_mem_id = $_oauth_data;            $_mo_model = new MemoauthModel();            $_mo_data = $_mo_model->getInfoByOpenId($type, $this->oauth_data['openid']);            if (empty($_mo_data)) {                $this->addOauth($_mem_id, $type, $this->oauth_data, $game_rq->getHAppId(), $_conf);            }            /* 登陆成功 */            $_mem_data = MemCache::ins()->getInfoById($_mem_id);            $_mem_data['guided_agent_id'] = $channel->getAgentId();            $_rdata = $this->getReturnData($_mem_data, $game_rq->getHAppId(), $device->getDeviceType());            $this->insertLoginLog($game_rq, $channel, $device, $member, $_rdata);            return $this->retSucMsg(MemberStatus::NO_ERROR, $_rdata);        } elseif (is_array($_oauth_data)) {            /* 用户信息 查询openid是否对应玩家ID */            $_mo_model = new MemoauthModel();            $_mo_data = $_mo_model->getInfoByOpenId($type, $_oauth_data['openid']);            $_mem_id = isset($_mo_data['mem_id']) ? $_mo_data['mem_id'] : 0;            if (empty($_mo_data['id']) && empty($_mem_id)) {                /* 玩家注册 */                $_mem_data = $this->oAuthReg($type, $_oauth_data, $game_rq, $channel, $device, $member, $_conf);                $member->setIsReg(MemConst::MEM_IS_REG);                $_mem_data['is_reg'] = MemConst::MEM_IS_REG;                /* LTV统计 */                $_ltv_class = new \ltv\Ltv();                $_ltv_class->reg($_mem_data['app_id'], $_mem_data['agent_id'], $_mem_data['create_time']);                /* 生成支付小程序码 */            } elseif (empty($_mo_data['id']) && !empty($_mem_id)) {                /* 登陆成功 */                $this->addOauth($_mem_id, $type, $_oauth_data, $game_rq->getHAppId(), $_conf);                $_mem_data = MemCache::ins()->getInfoById($_mem_id);            } else {                /* 有第三方信息 未绑定玩家 */                $_mem_id = $this->memReg($type, $_oauth_data, $game_rq, $channel, $device, $member);                $_mo_data['mem_id'] = $_mem_id;                $_mo_model->updateOauth($type, $_oauth_data['openid'], $_mo_data);                $_mem_data = MemCache::ins()->getInfoById($_mem_id);            }            $_mem_data['guided_agent_id'] = $channel->getAgentId();            $_rdata = $this->getReturnData($_mem_data, $game_rq->getHAppId(), $device->getDeviceType());            $this->insertLoginLog($game_rq, $channel, $device, $member, $_rdata);            return $this->retSucMsg(MemberStatus::NO_ERROR, $_rdata);        }        $_err_msg = 'func='.__FUNCTION__.'&class='.__CLASS__.'&oauth_data='                    .json_encode($_oauth_data).'&data='.json_encode(                        array($type, $code, $from, $game_rq->getHAppId(), $_conf)                    );        Log::write($_err_msg, Log::ERROR);        return $this->retErrMsg(MemberStatus::UNKNOWN_ERROR);    }    /**     * @param string $type 登陆类型     * @param string $code     * @param string $from     *     * @param int    $app_id     *     * @param array  $_conf     *     * @return array|bool|string array 表示用户所有信息  false 表示获取失败  string 为玩家ID     */    public function getOauthDataByCode($type, $code, $from, $app_id = 0, $_conf = []) {        //Log::error('$type$type$type'.json_encode($type));        try {            if (OauthConst::OAUTH_MP == $type) {                $_conf = (new GameMini())->getLoginConf($app_id);                if (empty($_conf)) {                    return false;                }            }            $_oauth_class = OAuthLib::ins($type, $_conf);            $_oauth_class->setCallback($this->getCallbackUrl($type));            $_token = $_oauth_class->getAccessToken($code, $from);            /* Session 设置  设置第三方登陆Session *///            (new HuoSession())->setOauthSession($_token);            $_open_id = $_token['openid'];            $_oauth_data = $_oauth_class->getUserInfo();            $this->oauth_data = $_oauth_data;            //Log::error('$_oauth_data111'.json_encode($_oauth_data));            $_mo_model = new MemoauthModel();            $_mo_data = $_mo_model->getInfoByOpenId($type, $_open_id);            if (!empty($_mo_data['id'])) {      // 老玩家                $_mem_id = $_mo_data['mem_id'];                /*  更新信息 */                if (($_mo_data['unionid'] == $_mo_data['openid'] && $_oauth_data['unionid'] != $_oauth_data['openid'])                    || 0 == $_mem_id) {                    $_mem_id = $this->getMemIdByUnionId($type, $_oauth_data['unionid']);                    /* 插入更多信息 */                    $_mo_data['unionid'] = $_oauth_data['unionid'];                    $_mo_data['nickname'] = $_oauth_data['nickname'];                    $_mo_data['gender'] = $_oauth_data['gender'];                    $_mo_data['avatar'] = $_oauth_data['avatar'];                    $_mo_data['status'] = MemConst::STATUS_NORMAL;                    $_mo_data['expires_in'] = $_token['expires_in'];                    $_mo_data['mem_id'] = $_mem_id;                    $_mo_data['last_login_ip'] = get_client_ip(0, true);                    $_mem_data['avatar'] = $_mo_data['avatar'];                    $_mem_data['nickname'] = $_mo_data['nickname'];                    $_mem_data['status'] = MemConst::STATUS_NORMAL;                    MemCache::ins()->updateMem($_mem_id, $_mem_data);                }                $_mo_data['access_token'] = $_token['access_token'];                $_mo_data['expires_in'] = $_token['expires_in'];                $_mo_data['last_login_ip'] = get_client_ip(0, true);                $_mo_data['last_login_time'] = time();                if(empty($_mo_data['conf_id'])){                    if (!empty($app_id)) {                        $_mp_id = (new GameMini())->getMiniIdByAppId($app_id);                        $_mo_data['conf_id'] = (new MpConfModel())->getIdByMpId($_mp_id);                    }                }                $_mo_model->updateOauth($type, $_open_id, $_mo_data);                if (empty($_mem_id)) {                    return $_oauth_data;                }                return $_mem_id;            }            return $_oauth_data;        } catch (Exception $_e) {            $_err_msg = 'func='.__FUNCTION__.'&class='.__CLASS__.'&Exception'                        .$_e->getMessage().'&code'.$_e->getCode();            Log::write($_err_msg, Log::ERROR);            return false;        }    }    /**     * @param         $type     * @param         $oauth_data     * @param Game    $game_rq     * @param Channel $channel     * @param Device  $device     * @param Mem     $member     * @param array   $conf     *     * @return array|bool|mixed     */    public function oAuthReg(        $type, $oauth_data, Game $game_rq, Channel $channel, Device $device, Mem $member, $conf = []    ) {        $_mem_id = $this->memReg($type, $oauth_data, $game_rq, $channel, $device, $member);        $_rs = $this->addOauth($_mem_id, $type, $oauth_data, $game_rq->getHAppId(), $conf);        if (false != $_rs) {            return MemCache::ins()->getInfoById($_mem_id);        }        return false;    }    /**     * 玩家主表注册     *     * @param         $type     * @param         $oauth_data     * @param Game    $game_rq     * @param Channel $channel     * @param Device  $device     * @param Mem     $member     *     * @return string     */    public function memReg($type, $oauth_data, Game $game_rq, Channel $channel, Device $device, Mem $member) {        $_username = $this->genUsername($type);        $_password = StrUtils::getRandChars(8);        $member->setUsername($_username);        $member->setPassword($_password);        $member->setAvatar($oauth_data['avatar']);        $member->setNickname($oauth_data['nickname']);        /* Modified by ouzhongfu BEGIN 2020/4/9 ISSUES:11805 第三方注册设置为试玩账号,修改密码时不需输入原密码 */        /*if (empty($oauth_data['nickname'])) {            $member->setStatus(MemConst::STATUS_TRY);        }*/        $member->setStatus(MemConst::STATUS_TRY);        /* END 2020/4/9 ISSUES:11805 */        $_mem_id = $this->getMemIdByUnionId($type, $oauth_data['unionid']);        if (empty($_mem_id)) {            $_mem_data = (new Register())->reg($game_rq, $channel, $device, $member);            $_mem_id = $_mem_data['id'];        }        return $_mem_id;    }    private function addOauth($_mem_id, $type, $oauth_data, $app_id = 0, $conf = []) {        $_data['openid'] = $oauth_data['openid'];        $_data['from'] = $type;        $_data['access_token'] = $oauth_data['token']['access_token'];        $_data['unionid'] = $oauth_data['unionid'];        $_data['nickname'] = $oauth_data['nickname'];        $_data['country'] = !empty($oauth_data['country']) ? $oauth_data['country'] : '';        $_data['province'] = !empty($oauth_data['province']) ? $oauth_data['province'] : '';        $_data['city'] = !empty($oauth_data['city']) ? $oauth_data['city'] : '';        $_data['gender'] = $oauth_data['gender'];        $_data['avatar'] = $oauth_data['avatar'];        $_data['mem_id'] = $_mem_id;        $_data['status'] = empty($oauth_data['nickname']) ? MemConst::STATUS_TRY : MemConst::STATUS_NORMAL;        $_data['expires_in'] = $oauth_data['token']['expires_in'];        if (!empty($app_id)) {            $_mp_id = (new GameMini())->getMiniIdByAppId($app_id);            $_data['conf_id'] = (new MpConfModel())->getIdByMpId($_mp_id);        }        if (OauthConst::OAUTH_WEIXIN == $type) {  //微信            $_conf_id = get_val($conf, 'APP_KEY', '');            if (empty($_conf_id)) {                $_conf_id = get_val($oauth_data, 'app_key', '');            }            $_data['conf_id'] = (new MpConfModel())->getIdByMpId($_conf_id);        }        //扩展信息        $_more = [            'refresh_token' => !empty($oauth_data['token']['refresh_token']) ? $oauth_data['token']['refresh_token']                : '',        ];        $_data['more'] = json_encode($_more);        $_rs = (new MemoauthModel())->addOauth($_data);        if (false === $_rs) {            return false;        }        return MemCache::ins()->saveOpenIdCache($type, $_data['openid'], $_mem_id);    }    /**     * 通过OpenId 获取玩家ID     *     *     * @param string $type     * @param string $union_id     *     * @return string     */    public function getMemIdByUnionId($type, $union_id) {        $_mem_id = (new MemoauthModel())->getMemIdByUnionId($type, $union_id);        return $_mem_id;    }    /**     * 通过Token获取第三方信息     *     * @param $type     * @param $openid     * @param $access_token     *     * @return bool     */    public function getOauthDataByToken($type, $openid, $access_token) {        try {            $token['openid'] = $openid;            $token['access_token'] = $access_token;            $_oauth_class = OAuthLib::ins($type, [], $token);            return $_oauth_class->getUserInfo();        } catch (Exception $_e) {            $_err_msg = 'func='.__FUNCTION__.'&class='.__CLASS__.'&Exception'                        .$_e->getMessage().'&code'.$_e->getCode();            Log::write($_err_msg, Log::ERROR);            return false;        }    }    /**     * @param string $domain     */    public function setDomain($domain) {        $this->domain = $domain;    }    /**     * 通过code获取登陆信息     *     * @param         $type     * @param         $access_token     * @param         $openid     * @param         $from     * @param Game    $game_rq     * @param Channel $channel     * @param Device  $device     * @param Mem     $member     *     * @param array   $_conf     * @param         $oauth_app_key     *     * @return array|mixed     */    public function oauthLoginByAccessToken(        $type, $access_token, $openid, $from,        Game $game_rq, Channel $channel, Device $device, Mem $member, $_conf = [], $oauth_app_key = ''    ) {        $_oauth_data = $this->getOauthDataByAccessToken(            $type, $access_token, $openid, $from, $game_rq->getHAppId(), $_conf, $oauth_app_key        );        if (is_numeric($_oauth_data)) {            $_mem_id = $_oauth_data;            /* 登陆成功 */            $_mem_data = MemCache::ins()->getInfoById($_mem_id);            $_rdata = $this->getReturnData($_mem_data, $game_rq->getHAppId(), $device->getDeviceType());            $this->insertLoginLog($game_rq, $channel, $device, $member, $_rdata);            return $this->retSucMsg(MemberStatus::NO_ERROR, $_rdata);        } elseif (is_array($_oauth_data)) {            /* 用户信息 查询openid是否对应玩家ID */            $_mo_model = new MemoauthModel();            $_mo_data = $_mo_model->getInfoByOpenId($type, $_oauth_data['openid']);            $_mem_id = isset($_mo_data['mem_id']) ? $_mo_data['mem_id'] : 0;            if (empty($_mo_data['id']) && empty($_mem_id)) {                /* 玩家注册 */                $_mem_data = $this->oAuthReg($type, $_oauth_data, $game_rq, $channel, $device, $member, $_conf);                $member->setIsReg(MemConst::MEM_IS_REG);                $_mem_data['is_reg'] = MemConst::MEM_IS_REG;                /* 生成支付小程序码 */            } elseif (empty($_mo_data['id']) && !empty($_mem_id)) {                /* 登陆成功 */                $this->addOauth($_mem_id, $type, $_oauth_data, $game_rq->getHAppId(), $_conf);                $_mem_data = MemCache::ins()->getInfoById($_mem_id);            } else {                /* 有第三方信息 未绑定玩家 */                $_mem_id = $this->memReg($type, $_oauth_data, $game_rq, $channel, $device, $member);                $_mo_data['mem_id'] = $_mem_id;                $_mo_model->updateOauth($type, $_oauth_data['openid'], $_mo_data);                $_mem_data = MemCache::ins()->getInfoById($_mem_id);            }            $_rdata = $this->getReturnData($_mem_data, $game_rq->getHAppId(), $device->getDeviceType());            $this->insertLoginLog($game_rq, $channel, $device, $member, $_rdata);            return $this->retSucMsg(MemberStatus::NO_ERROR, $_rdata);        }        $_err_msg = 'func='.__FUNCTION__.'&class='.__CLASS__.'&oauth_data='                    .json_encode($_oauth_data).'&data='.json_encode(                        array($type, $access_token, $openid, $from, $game_rq->getHAppId(), $_conf)                    );        Log::write($_err_msg, Log::ERROR);        return $this->retErrMsg(MemberStatus::UNKNOWN_ERROR);    }    /**通过accesstoken获取信息     *     * @param       $type     * @param       $access_token     * @param       $openid     * @param       $from     * @param int   $app_id     * @param array $_conf     * @param       $oauth_app_key     *     * @return bool|string     */    public function getOauthDataByAccessToken($type, $access_token, $openid, $from, $app_id = 0, $_conf = [], $oauth_app_key = '') {        try {            if (OauthConst::OAUTH_MP == $type) {                $_conf = (new GameMini())->getLoginConf($app_id);                if (empty($_conf)) {                    return false;                }            }            $_token = [                'access_token' => $access_token,                'openid'       => $openid,                'oauth_app_key'=> $oauth_app_key,                'expires_in'   => '7200'            ];            $_oauth_class = OAuthLib::ins($type, $_conf, $_token);            $_oauth_class->setCallback($this->getCallbackUrl($type));            /* Session 设置  设置第三方登陆Session */            $_open_id = $openid;            $_oauth_data = $_oauth_class->getUserInfo();            $_mo_model = new MemoauthModel();            $_mo_data = $_mo_model->getInfoByOpenId($type, $_open_id);            if (!empty($_mo_data['id'])) {                $_mem_id = $_mo_data['mem_id'];                /*  更新信息 */                if (($_mo_data['unionid'] == $_mo_data['openid'] && $_oauth_data['unionid'] != $_oauth_data['openid'])                    || 0 == $_mem_id) {                    $_mem_id = $this->getMemIdByUnionId($type, $_oauth_data['unionid']);                    /* 插入更多信息 */                    $_mo_data['unionid'] = $_oauth_data['unionid'];                    $_mo_data['nickname'] = $_oauth_data['nickname'];                    $_mo_data['gender'] = $_oauth_data['gender'];                    $_mo_data['avatar'] = $_oauth_data['avatar'];                    $_mo_data['status'] = MemConst::STATUS_NORMAL;                    $_mo_data['expires_in'] = $_token['expires_in'];                    $_mo_data['mem_id'] = $_mem_id;                    $_mo_data['last_login_ip'] = get_client_ip(0, true);                    $_mem_data['avatar'] = $_mo_data['avatar'];                    $_mem_data['nickname'] = $_mo_data['nickname'];                    $_mem_data['status'] = MemConst::STATUS_NORMAL;                    MemCache::ins()->updateMem($_mem_id, $_mem_data);                }                $_mo_data['access_token'] = $_token['access_token'];                $_mo_data['expires_in'] = $_token['expires_in'];                $_mo_data['last_login_ip'] = get_client_ip(0, true);                $_mo_data['last_login_time'] = time();                $_mo_model->updateOauth($type, $_open_id, $_mo_data);                if (empty($_mem_id)) {                    return $_oauth_data;                }                return $_mem_id;            }            return $_oauth_data;        } catch (Exception $_e) {            $_err_msg = 'func='.__FUNCTION__.'&class='.__CLASS__.'&Exception'                        .$_e->getMessage().'&code'.$_e->getCode();            Log::write($_err_msg, Log::ERROR);            return false;        }    }}
 |