基于TP5、EasyWeChat、fastadmin微信小程序授权登录

第一种原生写法拉起登录

class Register extends Api
{
    protected $appid;
    protected $secret;
    protected $loginUrl;
    protected $noNeedLogin = ['login', 'saveUserInfo'];
    protected $noNeedRight = ['*'];
	
	// 基本配置
    public function _initialize()
    {
        parent::_initialize();
        $this->appid = get_addon_config("epay")['wechat']['miniapp_id'];
        $this->secret = get_addon_config("epay")['wechat']['miniapp_secret'];
        $this->loginUrl = get_addon_config("epay")['wechat']['miniapp_url'];
    }

    # 根据code获取sessionKey和openId
    public function login()
    {
        $code = $this->request->get('code');

        if (!$code) {
            $this->error('缺少必要参数code');
        }

        $url = sprintf($this->loginUrl, $this->appid, $this->secret, $code);

        $result = json_decode(file_get_contents($url),true);

        if (!$result) {
            $this->error('获取sessionKey和openId时异常');
        }

        if (!empty($result['errcode']) && $result['errcode'] != 0) {
            return ['code' => $result['errcode'], 'msg' => $result['errmsg']];
        }

        $this->success('获取信息成功', $result);
    }

    /* login() 输出结果
     * {
        "code":1,
        "msg":"获取信息成功",
        "time":"1619158127",
        "data":{
            "session_key":"u3mgBqx1GH8fNsx06Ja4FA==",
            "openid":"ooOoU5a6Ulb0-bXZqjlWsZowwVRc"
        }
    }*/

    # 获取用户基本信息
    public function saveUserInfo()
    {
        $params = $this->request->post();
        // 入参
        extract($params);

        $errCode = $this->decryptData($encryptedData, $iv, $data, $sessionKey, $this->appid);

        if ($errCode == 0) {
            $result = json_decode($data,true);

            $user = User::get(['openid' => $openid]);

            if (!empty($user)) {
                if ($user->status != 'normal') {
                    $this->error(__('Account is locked'));
                }
                // 更新用户数据
                $user->nickname = base64_decode(base64_encode($result['nickName']));
                $user->avatar = $result['avatarUrl'];
                $user->save();
                // 直接登陆
                $ret = $this->auth->direct($user->id);
            } else {
                // 拉起小程序登录
                $ret = $this->auth->wxMiniProgramLogin($result,$openid);
            }

            if ($ret) {
                $this->success('授权登录成功', $this->auth->getUserInfo());
            } else {
                $this->error('授权登录失败');
            }
        } else {
            $this->error('授权登录失败了');
        }
    }

    /*{
        "code":1,
        "msg":"授权登录成功",
        "time":"1619593469",
        "data":{
            "id":1,
            "nickname":"霍文霆",
            "avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTJoxeWibNOCabPKocbFBH1QjoFnFwUnIUF9D12xhpeHjVAEQWxmsnrsSWswoyW654zteF4AtHyeU4A\/132",
            "mobile":"18186518743",
            "score":0,
            "token":"9030eb92-1efc-42e4-9000-531222d94a06",
            "user_id":1,
            "createtime":1619593469,
            "expiretime":1622185469,
            "expires_in":2592000
        }
    }*/

    # 检验数据的真实性,并且获取解密后的明文.
    # @param $encryptedData string 加密的用户数据
    # @param $iv string 与用户数据一同返回的初始向量
    # @param $data string 解密后的原文
    # @return int 成功0,失败返回对应的错误码
    public function decryptData($encryptedData, $iv, &$data, $sessionKey, $appid)
    {
        if (strlen($sessionKey) != 24) {
            return -41001;
        }

        $aesKey = base64_decode($sessionKey);

        if (strlen($iv) != 24) {
            return -41002;
        }

        $aesIV = base64_decode($iv);
        $aesCipher = base64_decode($encryptedData);
        $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
        $dataObj = json_decode($result);

        if ($dataObj == NULL) {
            return -41003;
        }

        if ($dataObj->watermark->appid != $appid) {
            return -41003;
        }

        $data = $result;

        return 0;
    }
}

第二种EasyWeChat拉起登录,如果有不会安装EasyWeChat的新手可以去看看我的公众号授权登录

use EasyWeChat\Factory;

class Register extends Api
{
    protected $app;
    protected $config;
    protected $noNeedLogin = ['login', 'saveUserInfo'];
    protected $noNeedRight = ['*'];

    public function _initialize()
    {
        parent::_initialize();

        // 这里的配置信息可以写入基本配置里面,这里只是为了练手
        $this->config = [
            'app_id' => 'wx53ce******3dcd53',
            'secret' => 'c8c80544f7************0034acdab9',

            // 下面为可选项
            // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',

            'log' => [
                'level' => 'debug',
                'file'  =>  ROOT_PATH . '/public/logs/wxMiniProgramLogin.log'
            ]
        ];

        $this->app = Factory::miniProgram($this->config);
    }

    # 根据code获取sessionKey和openId
    public function login()
    {
        $code = $this->request->get('code');

        if (!$code) {
            $this->error('缺少必要参数code');
        }

        $result = $this->app->auth->session($code);

        /* $result 输出结果
         * Array (
            [session_key] => 0mZrSFu1K6vX7appQsrxOw==
            [openid]      => ooOoU5a6Ulb0-bXZqjlWsZowwVRc
        )*/

        if (!$result) {
            $this->error('获取sessionKey和openId时异常');
        }

        if (!empty($result['errcode']) && $result['errcode'] != 0) {
            return ['code' => $result['errcode'], 'msg' => $result['errmsg']];
        }

        $this->success('获取信息成功', $result);
    }

    /* login() 输出结果
     * {
        "code":1,
        "msg":"获取信息成功",
        "time":"1619163984",
        "data":{
            "session_key":"3uh+wLzDl47zHOEj4H4fSg==",
            "openid":"ooOoU5a6Ulb0-bXZqjlWsZowwVRc"
        }
    }*/

    # 获取用户基本信息
    public function saveUserInfo()
    {
        $params = $this->request->post();

        // 入参
        extract($params);

        if (empty($iv) || empty($openid) || empty($sessionKey) || empty($encryptedData)) {
            $this->error('缺少必要参数!');
        }

        $result = $this->app->encryptor->decryptData($sessionKey, $iv, $encryptedData);

        /* $result 输出结果
         * Array (
            [nickName]  => 霍文霆
            [gender]    => 1
            [language]  => zh_CN
            [city]      =>
            [province]  => Anhui
            [country]   => China
            [avatarUrl] => https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIwdDXLgfezLpDudf6gu0yD2VBE7dHgiaGFWT2HwRcNuN9paUSlCvPWaQtOSOPHpLtRxKzK7DtJiaHQ/132
            [watermark] => Array (
                [timestamp] => 1619163984
                [appid]     => wx53ce5308043dcd53
            )
        )*/

        $user = User::get(['openid' => $openid]);

        if (!empty($user)) {
            if ($user->status != 'normal') {
                $this->error(__('Account is locked'));
            }
            // 更新用户数据
            $user->nickname = base64_decode(base64_encode($result['nickName']));
            $user->avatar = $result['avatarUrl'];
            $user->save();
            // 直接登陆
            $ret = $this->auth->direct($user->id);
        } else {
            // 拉起小程序登录
            $ret = $this->auth->wxMiniProgramLogin($result,$openid);
        }

        if ($ret) {
            $this->success('授权登录成功', $this->auth->getUserInfo());
        } else {
            $this->error('授权登录失败');
        }
    }

    /* saveUserInfo() 输出结果
     * {
        "code":1,
        "msg":"授权登录成功",
        "time":"1619164807",
        "data":{
            "openid":"ooOoU5a6Ulb0-bXZqjlWsZowwVRc",
            "nickname":"霍文霆",
            "avatar":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/Q0j4TwGTfTIwdDXLgfezLpDudf6gu0yD2VBE7dHgiaGFWT2HwRcNuN9paUSlCvPWaQtOSOPHpLtRxKzK7DtJiaHQ\/132",
            "token":"20abd047-ea42-4a32-88b8-68efecafaec6",
            "user_id":1,
            "createtime":1619164807,
            "expiretime":1621756807,
            "expires_in":2592000
        }
    }*/
}

在 app\common\library 方法中添加如下方法(这是基于fastadmin开发的,可以作为参考,数据写入方式个人有个人的风格,我认为我既然用了这个框架那就用它自带封装好的,代码越精简越好,能少写就少写,能不写就不写,最大的提高代码复用率,这样后续如果有二开就会舒服很多)

    /**
     * 微信小程序注册用户
     *
     * @param string $username 用户名
     * @param string $password 密码
     * @param string $email    邮箱
     * @param string $mobile   手机号
     * @param array  $extend   扩展参数
     * @return boolean
     */
    public function wxMiniProgramLogin($result, $openid)
    {
        /* $result 打印结果
         * Array (
            [nickName]  => 霍文霆
            [gender]    => 1
            [language]  => zh_CN
            [city]      =>
            [province]  => Anhui
            [country]   => China
            [avatarUrl] => https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIwdDXLgfezLpDudf6gu0yD2VBE7dHgiaGFWT2HwRcNuN9paUSlCvPWaQtOSOPHpLtRxKzK7DtJiaHQ/132
            [watermark] => Array (
                [timestamp] => 1618847873
                [appid]     => wx53ce5308043dcd53
            )
        )*/

        $params = [
            'openid'    => $openid,
            'nickname'  => base64_decode(base64_encode($result['nickName'])),
            'avatar'    => $result['avatarUrl'],
            'jointime'  => time(),
            'joinip'    => request()->ip(),
            'logintime' => time(),
            'loginip'   => request()->ip(),
            'prevtime'  => time(),
            'status'    => 'normal'
        ];

        Db::startTrans();
        try {
            $user = User::create($params, true);
            $this->_user = User::get($user->id);
            //设置Token
            $this->_token = Random::uuid();
            Token::set($this->_token, $user->id, $this->keeptime);
            Db::commit();
        } catch (Exception $e) {
            $this->setError($e->getMessage());
            Db::rollback();
            return false;
        }

        return true;
    }
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值