PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集PHP建站技术分享-从入门到精通_各类知识收集

QQ:420220301 微信/手机:150-3210-7690
当前位置:首页 > CMS教程 > Fastadmin

第三方登录增加微信扫码登录(公众号与扫码账号同步)

管理员 2024-12-14
Fastadmin
70

新增修复(默认如果删除会员后不删除关联第三方账号数据,则再次使用第三方登录后导致白屏)
/application/admin/controller/user/User.php 增加删除关联三方登录账号

    /**     * 删除     * @param mixed $ids     */    public function del($ids = "")    {        appadminmodelUser::event('after_delete', function ($row) {            $third = get_addon_info('third');            if($third && $third['state']==1){                addonsthirdmodelThird::where('user_id', $row['id'])->delete();            }         });        parent::del($ids);    }

第一步需要在微信开放平台绑定公众号并创建网站应用
注:如果不绑定公众号,通过微信公众号登录时是无法获取unionid的,则无法与微信扫码登录做同步唯一判断

第二步执行sql增加字段

ALTER TABLE `fa_third` ADD COLUMN `unionid` varchar(50) NOT NULL DEFAULT '' COMMENT '第三方唯一uid' AFTER `openid`;

第三步配置第三方登录
_scan结尾的参数值填写微信开放平台申请的网站应用参数
image.png
增加扫码登录appid和appsecret
增加3个扫码登录参数
app_id_scan
app_secret_scan
scope_scan

以下为代码修改(修改代码基础 第三方登录版本号1.1.2)
如果版本号一致直接覆盖即可
如果不一致请对比修改
搜索修改关键词 CoderRay修改

/addons/third/library/Wechat.php

<?phpnamespace addonsthirdlibrary;use fastHttp;use thinkConfig;use thinkSession;/** * 微信 */class Wechat{       const GET_AUTH_SCAN_CODE_URL = "https://open.weixin.qq.com/connect/qrconnect";//CoderRay修改    const GET_AUTH_CODE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize";    const GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";    const GET_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo";    /**     * 配置信息     * @var array     */    private $config = [];    public function __construct($options = [])    {        if ($config = Config::get('third.wechat')) {            $this->config = array_merge($this->config, $config);        }        $this->config = array_merge($this->config, is_array($options) ? $options : []);        //CoderRay修改 start         $this->isWechat = stripos(request()->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;        if(!$this->isWechat){            $this->config['app_id'] = $this->config['app_id_scan'];            $this->config['app_secret'] = $this->config['app_secret_scan'];            $this->config['scope'] = $this->config['scope_scan'];        }        //CoderRay修改 end    }    /**     * 登陆     */    public function login()    {        header("Location:" . $this->getAuthorizeUrl());    }    /**     * 获取authorize_url     */    public function getAuthorizeUrl()    {        $state = md5(uniqid(rand(), true));        Session::set('state', $state);        $queryarr = array(            "appid"         => $this->config['app_id'],            "redirect_uri"  => $this->config['callback'],            "response_type" => "code",            "scope"         => $this->config['scope'],            "state"         => $state,        );        request()->isMobile() && $queryarr['display'] = 'mobile';        //CoderRay修改 start        if($this->isWechat){            $url = self::GET_AUTH_CODE_URL . '?' . http_build_query($queryarr) . '#wechat_redirect';        }else{            $url = self::GET_AUTH_SCAN_CODE_URL . '?' . http_build_query($queryarr) . '#wechat_redirect';        }        //CoderRay修改 end        return $url;    }    /**     * 获取用户信息     * @param array $params     * @return array     */    public function getUserInfo($params = [])    {        $params = $params ? $params : request()->get();        if (isset($params['access_token']) || (isset($params['state']) && $params['state'] == Session::get('state') && isset($params['code']))) {            //获取access_token            $data = isset($params['code']) ? $this->getAccessToken($params['code']) : $params;            $access_token = isset($data['access_token']) ? $data['access_token'] : '';            $refresh_token = isset($data['refresh_token']) ? $data['refresh_token'] : '';            $expires_in = isset($data['expires_in']) ? $data['expires_in'] : 0;            if ($access_token) {                $openid = isset($data['openid']) ? $data['openid'] : '';                $unionid = isset($data['unionid']) ? $data['unionid'] : '';                                //CoderRay修改 start                if(!$this->isWechat){                    $scope = 'snsapi_login';                }else{                    $scope = 'snsapi_userinfo';                }                //CoderRay修改 end                if (stripos($this->config['scope'], $scope) !== false) {//CoderRay修改                    //获取用户信息                    $queryarr = [                        "access_token" => $access_token,                        "openid"       => $openid,                        "lang"         => 'zh_CN'                    ];                    $ret = Http::get(self::GET_USERINFO_URL, $queryarr);                    $userinfo = (array)json_decode($ret, true);                    if (!$userinfo || isset($userinfo['errcode'])) {                        return [];                    }                    $userinfo = $userinfo ? $userinfo : [];                    $userinfo['avatar'] = isset($userinfo['headimgurl']) ? $userinfo['headimgurl'] : '';                } else {                    $userinfo = [];                }                $data = [                    'access_token'  => $access_token,                    'refresh_token' => $refresh_token,                    'expires_in'    => $expires_in,                    'openid'        => $openid,                    'unionid'       => $unionid,                    'userinfo'      => $userinfo                ];                return $data;            }        }        return [];    }    /**     * 获取access_token     * @param string code     * @return array     */    public function getAccessToken($code = '')    {        if (!$code) {            return [];        }        $queryarr = array(            "appid"      => $this->config['app_id'],            "secret"     => $this->config['app_secret'],            "code"       => $code,            "grant_type" => "authorization_code",        );        $response = Http::get(self::GET_ACCESS_TOKEN_URL, $queryarr);        $ret = (array)json_decode($response, true);        return $ret ? $ret : [];    }}

/addons/third/library/Service.php

<?phpnamespace addonsthirdlibrary;use addonsthirdmodelThird;use appcommonmodelUser;use fastRandom;use thinkDb;use thinkexceptionPDOException;/** * 第三方登录服务类 * * @author Karson */class Service{    /**     * 第三方登录     * @param string $platform 平台     * @param array  $params   参数     * @param array  $extend   会员扩展信息     * @param int    $keeptime 有效时长     * @return boolean     */    public static function connect($platform, $params = [], $extend = [], $keeptime = 0)    {        $time = time();        $values = [            'platform'      => $platform,            'openid'        => $params['openid'],            'unionid'       => isset($params['unionid'])?$params['unionid']:'',//CoderRay修改            'openname'      => isset($params['userinfo']['nickname']) ? $params['userinfo']['nickname'] : '',            'access_token'  => $params['access_token'],            'refresh_token' => $params['refresh_token'],            'expires_in'    => $params['expires_in'],            'logintime'     => $time,            'expiretime'    => $time + $params['expires_in'],        ];        $auth = appcommonlibraryAuth::instance();        $auth->keeptime($keeptime);        //CoderRay修改 start        if(isset($params['unionid']) && !empty($params['unionid'])){            $third = Third::get(['platform' => $platform, 'unionid' => $params['unionid']]);            if(!$third){                $third = Third::get(['platform' => $platform, 'openid' => $params['openid']]);            }        }else{            $third = Third::get(['platform' => $platform, 'openid' => $params['openid']]);        }        //CoderRay修改 end           if ($third) {            $user = User::get($third['user_id']);            if (!$user) {                return false;            }            $third->save($values);            return $auth->direct($user->id);        } else {            // 先随机一个用户名,随后再变更为u+数字id            $username = Random::alnum(20);            $password = Random::alnum(6);            $domain = request()->host();            Db::startTrans();            try {                // 默认注册一个会员                $result = $auth->register($username, $password, $username . '@' . $domain, '', $extend);                if (!$result) {                    return false;                }                $user = $auth->getUser();                $fields = ['username' => 'u' . $user->id, 'email' => 'u' . $user->id . '@' . $domain];                if (isset($params['userinfo']['nickname'])) {                    $fields['nickname'] = $params['userinfo']['nickname'];                }                if (isset($params['userinfo']['avatar'])) {                    $fields['avatar'] = htmlspecialchars(strip_tags($params['userinfo']['avatar']));                }                // 更新会员资料                $user = User::get($user->id);                $user->save($fields);                // 保存第三方信息                $values['user_id'] = $user->id;                Third::create($values);                Db::commit();            } catch (PDOException $e) {                Db::rollback();                $auth->logout();                return false;            }            // 写入登录Cookies和Token            return $auth->direct($user->id);        }    }}

/addons/third/controller/Index.php

<?phpnamespace addonsthirdcontroller;use addonsthirdlibraryApplication;use addonsthirdlibraryService;use addonsthirdmodelThird;use thinkaddonsController;use thinkConfig;use thinkCookie;use thinkHook;use thinkLang;use thinkSession;/** * 第三方登录插件 */class Index extends Controller{    protected $app = null;    protected $options = [];    public function _initialize()    {        parent::_initialize();        $config = get_addon_config('third');        $this->app = new Application($config);    }    /**     * 插件首页     */    public function index()    {        if (!appadminlibraryAuth::instance()->id) {            $this->error('当前插件暂无前台页面');        }        $platformList = [];        if ($this->auth->id) {            $platformList = Third::where('user_id', $this->auth->id)->column('platform');        }        $this->view->assign('platformList', $platformList);        return $this->view->fetch();    }    /**     * 发起授权     */    public function connect()    {        $platform = $this->request->param('platform');        $url = $this->request->request('url', $this->request->server('HTTP_REFERER', '/'), 'trim');        if (!$this->app->{$platform}) {            $this->error(__('Invalid parameters'));        }        if ($url) {            Session::set("redirecturl", $url);        }        // 跳转到登录授权页面        $this->redirect($this->app->{$platform}->getAuthorizeUrl());        return;    }    /**     * 通知回调     */    public function callback()    {        $auth = $this->auth;        //监听注册登录注销的事件        Hook::add('user_login_successed', function ($user) use ($auth) {            $expire = input('post.keeplogin') ? 30 * 86400 : 0;            Cookie::set('uid', $user->id, $expire);            Cookie::set('token', $auth->getToken(), $expire);        });        Hook::add('user_register_successed', function ($user) use ($auth) {            Cookie::set('uid', $user->id);            Cookie::set('token', $auth->getToken());        });        Hook::add('user_logout_successed', function ($user) use ($auth) {            Cookie::delete('uid');            Cookie::delete('token');        });        $platform = $this->request->param('platform');        // 成功后返回之前页面        $url = Session::has("redirecturl") ? Session::pull("redirecturl") : url('index/user/index');        // 授权成功后的回调        $userinfo = $this->app->{$platform}->getUserInfo();        if (!$userinfo) {            $this->error(__('操作失败'), $url);        }        Session::set("{$platform}-userinfo", $userinfo);        //判断是否启用账号绑定        //CoderRay修改 start        if(isset($userinfo['unionid']) && !empty($userinfo['unionid'])){            $third = Third::get(['platform' => $platform, 'unionid' => $userinfo['unionid']]);            if(!$third){                $third = Third::get(['platform' => $platform, 'openid' => $userinfo['openid']]);            }        }else{            $third = Third::get(['platform' => $platform, 'openid' => $userinfo['openid']]);        }        //CoderRay修改 end         if (!$third) {            $config = get_addon_config('third');            //要求绑定账号或会员当前是登录状态            if ($config['bindaccount'] || $this->auth->id) {                $this->redirect(url('index/third/prepare') . "?" . http_build_query(['platform' => $platform, 'url' => $url]));            }        }        $loginret = Service::connect($platform, $userinfo);        if ($loginret) {            $this->redirect($url);        }    }    /**     * 绑定账号     */    public function bind()    {        $platform = $this->request->request('platform', $this->request->param('platform', ''));        $url = $this->request->get('url', $this->request->server('HTTP_REFERER'));        $redirecturl = url("index/third/bind") . "?" . http_build_query(['platform' => $platform, 'url' => $url]);        $this->redirect($redirecturl);        return;    }    /**     * 解绑账号     */    public function unbind()    {        $platform = $this->request->request('platform', $this->request->param('platform', ''));        $url = $this->request->get('url', $this->request->server('HTTP_REFERER'));        $redirecturl = url("index/third/unbind") . "?" . http_build_query(['platform' => $platform, 'url' => $url]);        $this->redirect($redirecturl);        return;    }}

/application/index/controller/Third.php

<?phpnamespace appindexcontroller;use addonsthirdlibraryApplication;use appcommoncontrollerFrontend;use thinkLang;use thinkSession;/** * 第三方登录控制器 */class Third extends Frontend{    protected $noNeedLogin = ['prepare'];    protected $noNeedRight = ['*'];    protected $app = null;    protected $options = [];    protected $layout = 'default';    public function _initialize()    {        parent::_initialize();        $config = get_addon_config('third');        $this->app = new Application($config);    }    /**     * 准备绑定     */    public function prepare()    {        $platform = $this->request->request('platform');        $url = $this->request->get('url', '/');        if ($this->auth->id) {            $this->redirect(url("index/third/bind") . "?" . http_build_query(['platform' => $platform, 'url' => $url]));        }        // 授权成功后的回调        $userinfo = Session::get("{$platform}-userinfo");        if (!$userinfo) {            $this->error("操作失败,请返回重度");        }        Lang::load([            APP_PATH . 'index' . DS . 'lang' . DS . $this->request->langset() . DS . 'user' . EXT,        ]);        $this->view->assign('userinfo', $userinfo['userinfo']);        $this->view->assign('platform', $platform);        $this->view->assign('url', $url);        $this->view->assign('bindurl', url("index/third/bind") . '?' . http_build_query(['platform' => $platform, 'url' => $url]));        $this->view->assign('captchaType', config('fastadmin.user_register_captcha'));        $this->view->assign('title', "账号绑定");        return $this->view->fetch();    }    /**     * 绑定账号     */    public function bind()    {        $platform = $this->request->request('platform');        $url = $this->request->get('url', $this->request->server('HTTP_REFERER'));        if (!$platform) {            $this->error("参数不正确");        }        // 授权成功后的回调        $userinfo = Session::get("{$platform}-userinfo");        if (!$userinfo) {            $this->redirect(addon_url('third/index/connect', [':platform' => $platform]) . '?url=' . urlencode($url));        }        $third = addonsthirdmodelThird::where('user_id', $this->auth->id)->where('platform', $platform)->find();        if ($third) {            $this->error("已绑定账号,请勿重复绑定");        }        $time = time();        $values = [            'platform'      => $platform,            'user_id'       => $this->auth->id,            'unionid'       => isset($userinfo['unionid'])?$userinfo['unionid']:'',//CoderRay修改            'openid'        => $userinfo['openid'],            'openname'      => isset($userinfo['userinfo']['nickname']) ? $userinfo['userinfo']['nickname'] : '',            'access_token'  => $userinfo['access_token'],            'refresh_token' => $userinfo['refresh_token'],            'expires_in'    => $userinfo['expires_in'],            'logintime'     => $time,            'expiretime'    => $time + $userinfo['expires_in'],        ];        $third = addonsthirdmodelThird::create($values);        if ($third) {            $this->success("账号绑定成功", $url);        } else {            $this->error("账号绑定失败,请重试", $url);        }    }    /**     * 解绑账号     */    public function unbind()    {        $platform = $this->request->request('platform');        $third = addonsthirdmodelThird::where('user_id', $this->auth->id)->where('platform', $platform)->find();        if (!$third) {            $this->error("未找到指定的账号绑定信息");        }        $third->delete();        $this->success("账号解绑成功");    }}


希望以上内容对你有所帮助!如果还有其他问题,请随时提问。 各类知识收集 拥有多年CMS企业建站经验,对 iCMS, LeCMS, ClassCMS, Fastadmin, PbootCMS, PHPCMS, 易优CMS, YzmCMS, 讯睿CMS, 极致CMS, Wordpress, HkCMS, YznCMS, WellCMS, ThinkCMF, 等各类cms的相互转化,程序开发,网站制作,bug修复,程序杀毒,插件定制都可以提供最佳解决方案。

扫码关注

qrcode

QQ交谈

回顶部