基于thinkphp5.1而成的小程序登录后台代码

小程序登录后台代码

经过几天测试,把官方文档集成到了一个控制器下,解决了解密访问小程序域名的难题。

下面放置代码

<?php


namespace app\home\controller;

use think\Controller;
use think\Exception;

class Wxchat extends Controller
{
    
    
    //微信登录
    public function wxlogin()
    {
    
    
        $get = input('get.');
        $param['appid'] = '*********************';    //小程序id
        $param['secret'] = '*********************';    //小程序密钥
        $param['js_code'] = $this->define_str_replace($get['code']);
        $param['grant_type'] = 'authorization_code';
        $http_key = $this->httpCurl('https://api.weixin.qq.com/sns/jscode2session', $param, 'GET');
        $session_key = json_decode($http_key, true);
        if (!empty($session_key['session_key'])) {
    
    
            $appid = $param['appid'];
            $encrypteData = $get['encryptedData'];
			//return json($encrypteData);
            $iv = $this->define_str_replace($get['iv']);
            $errCode = $this->decryptData($appid, $session_key['session_key'], $encrypteData, $iv);
            //把appid写入到数据库中
            $data['openid'] = $errCode['openId'];
            $data['username'] = $errCode['nickName'];
            $data['avatar'] = $errCode['avatarUrl'];
            $data['sex'] = $errCode['gender'];
            $data['district'] = $errCode['district'];
            $data['province'] = $errCode['province'];
            $data['city'] = $errCode['city'];
            $data['reg_time'] = time();
            if (false == db('users')->where(['openid' => $data['openid']])->find()) {
    
    
                db('users')->insert($data);
                $value = db('users')->where(['openid' => $data['openid']])->find();
            } else {
    
    
                $value = db('users')->where(['openid' => $data['openid']])->find();
            }
            return json($value);
        } else {
    
    
            echo '获取session_key失败!';
        }
    }
    /**
     * 发送HTTP请求方法
     * @param string $url 请求URL
     * @param array $params 请求参数
     * @param string $method 请求方法GET/POST
     * @return array  $data   响应数据
     */
    function httpCurl($url, $params, $method = 'POST', $header = array(), $multi = false)
    {
    
    
        date_default_timezone_set('PRC');
        $opts = array(
            CURLOPT_TIMEOUT => 30,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            CURLOPT_HTTPHEADER => $header,
            CURLOPT_COOKIESESSION => true,
            CURLOPT_FOLLOWLOCATION => 1,
            CURLOPT_COOKIE => session_name() . '=' . session_id(),
        );
        /* 根据请求类型设置特定参数 */
        switch (strtoupper($method)) {
    
    
            case 'GET':
                // $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
                // 链接后拼接参数  &  非?
                $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
                break;
            case 'POST':
                //判断是否传输文件
                $params = $multi ? $params : http_build_query($params);
                $opts[CURLOPT_URL] = $url;
                $opts[CURLOPT_POST] = 1;
                $opts[CURLOPT_POSTFIELDS] = $params;
                break;
            default:
                throw new Exception('不支持的请求方式!');
        }
        /* 初始化并执行curl请求 */
        $ch = curl_init();
        curl_setopt_array($ch, $opts);
        $data = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);
        if ($error) throw new Exception('请求发生错误:' . $error);
        return $data;
    }

    /**
     * 微信信息解密
     * @param string $appid 小程序id
     * @param string $sessionKey 小程序密钥
     * @param string $encryptedData 在小程序中获取的encryptedData
     * @param string $iv 在小程序中获取的iv
     * @return array 解密后的数组
     */
    function decryptData($appid, $sessionKey, $encryptedData, $iv)
    {
    
    
        $OK = 0;
        $IllegalAesKey = -41001;
        $IllegalIv = -41002;
        $IllegalBuffer = -41003;
        $DecodeBase64Error = -41004;

        if (strlen($sessionKey) != 24) {
    
    
            return $IllegalAesKey;
        }
        $aesKey = base64_decode($sessionKey);

        if (strlen($iv) != 24) {
    
    
            return $IllegalIv;
        }
        $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 $IllegalBuffer;
        }
        if ($dataObj->watermark->appid != $appid) {
    
    
            return $DecodeBase64Error;
        }
        $data = json_decode($result, true);

        return $data;

    }

    /**
     * 请求过程中因为编码原因+号变成了空格
     * 需要用下面的方法转换回来
     */
    function define_str_replace($data)
    {
    
    
        return str_replace(' ', '+', $data);
    }
}

最后

任何一个不熟悉的功能都需要耐心慢慢的调整,往往你会发现,其实错误点只是很小很小的一处细节,祝大家写代码都不出问题。

猜你喜欢

转载自blog.csdn.net/lo6064200/article/details/108070693