php
签名算法详见签名算法
/**
* 生成微信公众号签名
* @param string url 前端微信分享页面的url全地址
*/
public function getWxShareSign()
{
$access_token = $this->getAccessToken(); //获取微信access_token
$ticket = $this->getJsapiTicket($access_token); //获取微信ticket
$id=request()->param('id/d');//前端传来的参数id
$signData['jsapi_ticket'] = $ticket;
$signData['noncestr'] = 'abs1004';
$signData['timestamp'] = time();
$signData['url'] =request()->domain().'/detail?id='.$id;//当前网页的URL,重点
$sign = $this->makeWxSha1Sign($signData); // 生成微信签名
$signData['sign'] = $sign;
$signData['appId'] = config('wx_info')['AppID'];
// halt($signData);
return json($signData); // jsapi_ticket, noncestr, timestamp, sign 都返回给前端,供前端页面微信验签使用
}
/**
* 获取公众号access token
*/
public function getAccessToken(){
$appid=config('wx_info')['AppID'];
$secret=config('wx_info')['AppSecret'];
$time=db('token')->where('id',1)->find();//有效期7200秒,开发者必须在自己的服务全局缓存access_token
$url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret"; //获取token
if(!empty($time)&&$time){
if(time()-$time['time']>7200){
$res=file_get_contents($url);
db('token')->where('id',1)->update(['time'=>time(),'token'=>json_decode($res,true)['access_token']]);
return json_decode($res,true)['access_token'];
}else{
return $time['token'];
}
}else{
$res=file_get_contents($url);
db('token')->insert(['time'=>time(),'token'=>json_decode($res,true)['access_token']]);
return json_decode($res,true)['access_token'];
}
}
/**
*获取jsapi_ticket
*/
public function getJsapiTicket($token){
$time=db('token')->where('id',2)->find();//有效期7200秒,开发者必须在自己的服务全局缓存access_token
$url="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$token&type=jsapi"; //获取jsapi_ticket
if(!empty($time)&&$time){
if(time()-$time['time']>7200){
$res=file_get_contents($url);
db('token')->where('id',2)->update(['time'=>time(),'token'=>json_decode($res,true)['ticket']]);
return json_decode($res,true)['ticket'];
}else{
return $time['token'];
}
}else{
$res=file_get_contents($url);
db('token')->insert(['time'=>time(),'token'=>json_decode($res,true)['ticket']]);
return json_decode($res,true)['ticket'];
}
}
//生成 sha1 签名
private function makeWxSha1Sign($arr){
$str = "";
//升序数组的键
$keyArr = [];
foreach ($arr as $k => $v) {
array_push($keyArr,$k);
}
sort($keyArr);
reset($keyArr);
//升序数组的字符串拼接,删除signature
foreach ($keyArr as $key => $value) {
$linker = '';
if($key!=0){
$linker = '&';
}
$str .= $linker.$value.'='.$arr[$value];
}
// log_result('wxshare signStr='.$str);
//字符串SHA1
$signature = sha1($str);
return $signature;
}
js
<script src="https://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
$.post("{:url('getWxShareSign')}",{id:5},function(res){
// console.log(res.sign);
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: res.appId, // 必填,公众号的唯一标识
timestamp: res.timestamp, // 必填,生成签名的时间戳
nonceStr: res.noncestr, // 必填,生成签名的随机串
signature: res.sign, // 必填,签名,见附录1
jsApiList: ['onMenuShareAppMessage','onMenuShareTimeline'], // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
});
})
wx.ready(function() {
// 分享到朋友圈
wx.onMenuShareTimeline({
title: "这是标题", // 分享标题
desc: "这是描述", // 分享描述
link: '", // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
success: function() {
// 用户确认分享后执行的回调函数
},
cancel: function() {
// 用户取消分享后执行的回调函数
},
});
// 分享给朋友
wx.onMenuShareAppMessage({
title: "这是标题", // 分享标题
desc: "这是描述", // 分享描述
link: '", // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
imgUrl: '', // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function() {
// 用户确认分享后执行的回调函数
},
cancel: function() {
// 用户取消分享后执行的回调函数
},
});
})
wx.error(function(res) {
// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
// console.log('weixin 验证失败');
// console.log(res);
});
</script>