小程序心得
1. 小程序初次审核需要7天时间,上线请预留充足的时间。以后修改代码,每修改一次,审核时间2小时左右。
2.小程序码建议使用无限制的二维码接口。
3.token建议缓存2小时以内,并统一调用。
4.小程序与后端交互数据,接口和域名必须要https。
5.前后端数据输出,需要加解密。
php端解密代码类:
class Util_XiaoWechat
{
private $appid;
private $sessionKey;
public static $OK = 0;
public static $IllegalAesKey = -41001;
public static $IllegalIv = -41002;
public static $IllegalBuffer = -41003;
public static $DecodeBase64Error = -41004;
/**
* 构造函数
* @param $sessionKey string 用户在小程序登录后获取的会话密钥
* @param $appid string 小程序的appid
*/
public function __construct( $appid, $sessionKey)
{
$this->sessionKey = $sessionKey;
$this->appid = $appid;
}
/**
* 检验数据的真实性,并且获取解密后的明文.
* @param $encryptedData string 加密的用户数据
* @param $iv string 与用户数据一同返回的初始向量
* @param $data string 解密后的原文
*
* @return int 成功0,失败返回对应的错误码
*/
public function decryptData( $encryptedData, $iv, &$data )
{
if (strlen($this->sessionKey) != 24) {
return self::$IllegalAesKey;
}
$aesKey = base64_decode($this->sessionKey);
if (strlen($iv) != 24) {
return self::$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 self::$IllegalBuffer;
}
if( $dataObj->watermark->appid != $this->appid )
{
return self::$IllegalBuffer;
}
$data = $result;
return self::$OK;
}
}
业务代码:
获取token写法:
//通用get请求方法
public static function ($url){
$info=curl_init();
curl_setopt($info,CURLOPT_RETURNTRANSFER,true);
curl_setopt($info,CURLOPT_HEADER,0);
curl_setopt($info,CURLOPT_NOBODY,0);
curl_setopt($info,CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($info,CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($info,CURLOPT_URL,$url);
$output= curl_exec($info);
curl_close($info);
return $output;
}
//通用post请求方法
public static function curl_post($url,$data)
{
$ch = curl_init();
$params[CURLOPT_URL] = $url; //请求url地址
$params[CURLOPT_HEADER] = FALSE; //是否返回响应头信息
$params[CURLOPT_SSL_VERIFYPEER] = false;
$params[CURLOPT_SSL_VERIFYHOST] = false;
$params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回
$params[CURLOPT_POST] = true;
$params[CURLOPT_POSTFIELDS] = $data;
curl_setopt_array($ch, $params); //传入curl参数
$content = curl_exec($ch); //执行
curl_close($ch); //关闭连接
return $content;
}
//获取全局token
public static function getAccessToken(){
$app_id = Util_Conf::get('XIAO_WECHAT_APP_ID');
$app_secret = Util_Conf::get('XIAO_WECHAT_APP_SECRET');
$redis = Cache_Client::getInstance();
$access_token = $redis->get(self::$wx_access_token_key);
if(!$access_token){
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$app_id.'&secret='.$app_secret;
$res = self::curl_get($url);
$res = json_decode($res,true);
$access_token = $res['access_token'];
//同时缓存token
$redis->set(self::$wx_access_token_key,$access_token,self::$expire_time);
}
return $access_token;
}
交互逻辑:
前端获取登录凭证 js_code -> 服务端获取会话秘钥session_key 并缓存 -> 小程序引导用户获取手机号信息或者用户信息 -> 前端得到解密参数 iv 和 加密数据 - > 服务端根据iv 和和会话秘钥 session_key 和加密数据 进行解密数据 ,并将解密信息存取数据库 。
//授权手机号登录
public static function authorization($param){
$app_id = Util_Conf::get('XIAO_WECHAT_APP_ID');
$app_secret = Util_Conf::get('XIAO_WECHAT_APP_SECRET');
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid='.$app_id.'&secret='.$app_secret.'&js_code='.$param['js_code'].'&grant_type=authorization_code';
$arr = self::curl_get($url);
$arr = json_decode($arr, true);
$session_key = $arr['session_key'] ?? '';
if(!$session_key){
trigger_error($arr['errmsg'],256);
}
$session_key_info = [
'session_key' => $arr['session_key'],
'open_id' => $arr['openid'],
'union_id' => $arr['unionid'] ?? '',
];
//将会话秘钥信息存起来
$redis = Cache_Client::getInstance();
$redis->set(self::$session_key,json_encode($session_key_info),self::$session_key_expire);
Util_Log::write(Util_Log::LOG_TYPE_INFO,'========得到session_key========='.$session_key);
//解密手机号信息
$mobile_encryptedData = $param['mobile_encrypted_data'];
$mobile_iv = $param['mobile_iv'];
$pc = new Util_XiaoWechat($app_id, $session_key);
$mobile_errcode = $pc->decryptData($mobile_encryptedData, $mobile_iv, $data); //其中$data包含用户的所有数据
$phone_data = json_decode($data,true);
}
//生成小程序码:(得到的是图片的base64字符串)
public static function createQr($activity_id,$share_open_id,$width,$page){
$access_token = self::getAccessToken();
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$access_token;
$post_data = [
'scene' => 'id='.$activity_id.'&uid='.$share_open_id,
'width' => $width,
'page' => $page,
];
$post_data = json_encode($post_data);
$result = self::api_notice_increment($url,$post_data);
$type = getimagesizefromstring($result)['mime'];
$base64String = 'data:' . $type . ';base64,' . chunk_split(base64_encode($result));
$res = [
'base64_string' => $base64String,
];
return $res;
//echo '<img src="'.$base64String.'">';
}
public static function api_notice_increment($url, $data){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$tmpInfo = curl_exec($ch);
if (curl_errno($ch)) {
return false;
}else{
return $tmpInfo;
}
}
下面是 demo例子:
$access_token 可以直接去小程序网页调试工具获取
url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$access_token;
$post_data = [
'scene' => 'id=195&uid=CN3lHD9S', //参数
'page' => 'pages/activity/detail/index', //扫码需要去跳转的页面
// 'is_hyaline' => true,
// 'auto_color' => true,
];
$post_data = json_encode($post_data);
$result = api_notice_increment($url,$post_data);
$type = getimagesizefromstring($result)['mime'];
$base64String = 'data:' . $type . ';base64,' . chunk_split(base64_encode($result));
echo '<img src="'.$base64String.'">';
//相关的模板消息即订阅消息(例子: 前提是用户开启了订阅消息,不然会一直提示用户拒绝消息)
$access_token = '41_zdS0ic1aCdZIJERmHyKrPCjD0njpipB2u1vwAAw3m3TXYz7ZgZrX5aggKpJduw9i0AhEJhzOxWdFEICZ1GHgMbOzrXrTMtLIr2Y9BnG59QKKZmSyuRvIjgu3p1Z4z_4S9RkW4O-hAAXXXXXXXXX';
$open_id = 'omFyp5Dp67waG6GwSeA0TpsJNVpI';
$tempalate_id = '_ca1fOghCfHAHWNKcgo4LsQmAoTH7x5MK4JzW0QfcfU'; (在小程序里面配置的模板ID)
$params_post = [
'touser' => $open_id,
'template_id' => $tempalate_id,
'miniprogram_state' => 'trial',
'data' => [
'thing1' => [
'value' => '一起XXXX',
],
'phrase2' => [
'value' => '你的作品XXXX',
],
'thing3' => [
'value' => '可以发起好友助XXXXXXX',
],
],
];
$header_url = 'https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=' . $access_token ;;
$result = curlPost($header_url, json_encode($params_post));
$res = json_decode($res,true);
得到如下信息 :
{
"result": 0,
"msg": "ok",
"data": [
{
"errcode": 0,
"errmsg": "ok",
"xiao_weixin_id": "omFyp5Lrlda6s14BYZi1eBMhv5Zc"
}
]
}
证明发送成功。
龙卷风之殇

浙公网安备 33010602011771号