HEX
Server: nginx/1.28.1
System: Linux 10-41-63-61 6.8.0-31-generic #31-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 20 00:40:06 UTC 2024 x86_64
User: www (1001)
PHP: 7.4.33
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/ly.fwmnzf.com/addons/synclogin/controller/Index.php
<?php
// +----------------------------------------------------------------------
// | Yzncms [ 御宅男工作室 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018 http://yzncms.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 御宅男 <530765310@qq.com>
// +----------------------------------------------------------------------

// +----------------------------------------------------------------------
// | 第三方登录管理
// +----------------------------------------------------------------------
namespace addons\synclogin\Controller;

use addons\synclogin\ThinkSDK\Oauth;
use app\addons\util\AddonsBase;
use app\member\model\Member as Member_Model;
use app\member\service\User;
use think\Db;

class Index extends AddonsBase
{
    private $access_token = '';
    private $openid       = '';
    private $type         = '';
    private $token        = array();

    public function initialize()
    {
        parent::initialize();
        $this->getSession();
        $this->UserService = User::instance();
    }

    private function getSession()
    {
        $session            = session('SYNCLOGIN');
        $this->token        = $session['TOKEN'];
        $this->type         = $session['TYPE'];
        $this->openid       = $session['OPENID'];
        $this->access_token = $session['ACCESS_TOKEN'];
    }

    //登陆地址
    public function login()
    {
        $type = $this->request->param('type');
        empty($type) && $this->error('参数错误');
        //加载ThinkOauth类并实例化一个对象
        $sns          = Oauth::getInstance($type);
        $addon_config = get_addon_config('synclogin');
        if (0 == $addon_config['display']) {
            $sns->setDisplay('mobile');
        }
        //跳转到授权页面
        $this->redirect($sns->getRequestCodeURL());

    }

    //授权回调地址
    public function callback()
    {
        $type     = $this->request->param('type/s');
        $code     = $this->request->param('code/s');
        $is_login = $this->UserService->isLogin();
        if ($type == null || $code == null) {
            $this->error('参数错误');
        }
        $sns = Oauth::getInstance($type);
        // 获取TOKEN
        $token  = $sns->getAccessToken($code);
        $openid = !empty($token['unionid']) ? $token['unionid'] : $token['openid'];
        if (empty($token)) {
            $this->error('参数错误');
        }
        $session = array('TOKEN' => $token, 'TYPE' => $type, 'OPENID' => $openid, 'ACCESS_TOKEN' => $token['access_token']);
        session('SYNCLOGIN', $session);
        $this->getSession(); // 重新获取session
        //获取当前第三方登录用户信息
        if (is_array($token)) {
            $check = $this->checkIsSync(array('type_uid' => $openid, 'type' => $type));
            //是否完全登录状态
            /*if ($is_login && $check) {
            $this->loginWithoutpwd($is_login);
            }*/
            if ($is_login) {
                $this->dealIsLogin($is_login);
            } else {
                $addon_config = get_addon_config('synclogin');
                if ($addon_config['bind'] && !$check) {
                    $this->redirect(url('addons/synclogin/bind'));
                } else {
                    $this->prepare();
                }
            }
        } else {
            echo "获取第三方用户的基本信息失败";
        }
    }

    //绑定账号
    public function bind()
    {
        if (!$this->token) {
            $this->error('无效的token');
        }
        $tip               = $this->request->param('tip/s');
        $tip == '' && $tip = 'new';
        $this->assign('tip', $tip);
        return $this->fetch('bind');
    }

    //解绑账号
    public function unBind()
    {
        $aType = $this->request->param('type/s');
        if (empty($aType)) {
            $this->error('参数错误');
        }
        $uid = $this->UserService->isLogin();
        if (!$uid) {
            $this->error('请登录!');
        }

        $res = Db::name('sync_login')->where(array('uid' => $uid, 'type' => $aType))->delete();
        if ($res) {
            $this->success('取消绑定成功', url('member/index/profile'));
        }
        $this->error('取消绑定失败');
    }

    //绑定新账号
    public function newAccount()
    {
        $post   = $data   = $this->request->post();
        $result = $this->validate($data, 'addons\synclogin\validate\Member');
        if (true !== $result) {
            return $this->error($result);
        }
        $userid = $this->UserService->userRegister($data['username'], $data['password'], $data['email']);
        if ($userid > 0) {
            $this->addSyncLoginData($userid);
            $this->success('账号绑定成功!', url('member/index/index'));
        } else {
            $this->error('账号绑定失败,请重试!');
        }

    }

    //绑定已有账号
    public function bindAccount()
    {
        $username   = $this->request->param('username');
        $password   = $this->request->param('password');
        $cookieTime = $this->request->param('cookieTime', 0);
        $userInfo   = $this->UserService->loginLocal($username, $password, $cookieTime ? 86400 * 180 : 86400);
        if ($userInfo) {
            $this->addSyncLoginData($userInfo['id']);
            $this->success('账号绑定成功!', url('member/index/index'));
        } else {
            $this->error('账号绑定失败,请重试!');
        }
    }

    //跳过绑定或自动新增账号
    public function prepare()
    {
        $openid       = $this->openid;
        $type         = $this->type;
        $token        = $this->token;
        $access_token = $this->access_token;
        $map          = array('type_uid' => $openid, 'type' => $type);

        $user_info = \addons\synclogin\ThinkSDK\GetInfo::getInstance($type, $token);
        if ($uid = Db::name('sync_login')->field('uid')->where($map)->value('uid')) {
            $user = Member_Model::where('id', $uid)->find();
            if (!$user) {
                Db::name('sync_login')->where($map)->delete();
                $uid = $this->addData($user_info);
            } else {
                $syncdata['oauth_token']        = $access_token;
                $syncdata['oauth_token_secret'] = $openid;
                Db::name('sync_login')->where($map)->update($syncdata);
            }
        } else {
            $uid = $this->addData($user_info);
        }
        $this->loginWithoutpwd($uid);
    }

    //新增账号
    private function addData($user_info)
    {
        // 先随机一个用户名,随后再变更为u+数字id
        $username = genRandomString(10);
        $password = genRandomString(6);
        $domain   = request()->host();
        $uid      = $this->UserService->userRegister($username, $password, $username . '@' . $domain);
        if ($uid > 0) {
            $fields = ['username' => 'u' . $uid, 'email' => 'u' . $uid . '@' . $domain];
            if (isset($$user_info['nickname'])) {
                $fields['nickname'] = $$user_info['nickname'];
            }
            if (isset($$user_info['avatar'])) {
                $fields['avatar'] = htmlspecialchars(strip_tags($user_info['avatar']));
            }
            // 记录数据到sync_login表中
            $this->addSyncLoginData($uid);
            return $uid;
        } else {
            $this->error($this->UserService->getError() ?: '新增账号失败,请重试!');
        }
    }

    /**
     * loginWithoutpwd  使用uid直接登陆,不使用帐号密码
     */
    private function loginWithoutpwd($uid)
    {
        if (0 < $uid) {
            if ($this->UserService->direct($uid)) {
                //登陆用户
                $this->success('登陆成功!', url('member/index/index'));
            } else {
                $this->error('登录失败!');
            }
        }
    }

    /**
     * addSyncLoginData  增加sync_login表中数据
     */
    private function addSyncLoginData($uid)
    {
        $data['uid']                = $uid;
        $data['type_uid']           = $this->openid;
        $data['oauth_token']        = $this->access_token;
        $data['oauth_token_secret'] = $this->openid;
        $data['type']               = $this->type;

        if (!Db::name('sync_login')->where($data)->count()) {
            Db::name('sync_login')->insert($data);
        }
        return true;
    }

    protected function dealIsLogin($uid = 0)
    {
        $session = session('SYNCLOGIN');
        $openid  = $session['OPENID'];
        $type    = $session['TYPE'];
        if ($this->checkIsSync(array('type_uid' => $openid, 'type' => $type))) {
            $this->error('该帐号已经被绑定!');
        }
        $this->addSyncLoginData($uid);
        $this->success('绑定成功!', url('member/index/profile'));
    }

    private function checkIsSync($map = array())
    {
        if (Db::name('sync_login')->where($map)->count()) {
            return true;
        } else {
            return false;
        }
    }

}