微信公众号需要用到WEB开发中的JS-SDK,技术文档见:概述 | 微信开放文档
其中签名的生成涉及步骤有三步,1 获取access_token,2 获取Jsapi_ticket,3 生成signature
前两步调用因为有严格的次数限制,所以需要本地缓存,判断是否过期,生成新值,这里写了一个完整示例,自己也在用,所以分享出来,也可以封装成一个class,大家自己搞吧。
前提条件:设置IP白名单,JS接口安全域名,网页授权域名
1、第一步:记事本新建两个缓存文件 access_token.json, jsapi_ticket.json,内容输入空白json,即“{}”,设置权限可写入。
2、第二步,直接运行下面文件就可以输出signature了。我这里是为了传值给前端,所以用了json编码。
<?php
//设置微信appkey
$appid = '*************';
$appsecret = '*************';
$myurl = $_POST['myurl'];
function getSignature($myurl,$appid,$appsecret){
$timestamp = time();
$noncestr = rand_str();
$jsapi_ticket = getJsapi_ticket($appid,$appsecret);
$tmpStr = "jsapi_ticket={$jsapi_ticket}&noncestr={$noncestr}×tamp={$timestamp}&url={$myurl}";
//sha1加密,调用sha1函数
$signature = sha1($tmpStr);
$signature_Arr = array('timestamp'=>$timestamp,'noncestr'=>$noncestr,'signature'=>$signature,'appid'=>$appid,'myurl'=>$myurl); //【关联数组】
//json格式化,如:{"timestamp":"timestamp",...}
return json_encode($signature_Arr);
}
//获取Jsapi_ticket,判断是否过期,没过期直接读取缓存
function getJsapi_ticket($appid,$appsecret){
//获取access_token
$access_token = getToken($appid,$appsecret);
//读取缓存jsapi_ticket
$file = file_get_contents(dirname(__FILE__)."/jsapi_ticket.json",true);
$result = json_decode($file,true);
$timestr = time();
if(array_key_exists('expires',$result)){
if ($timestr > intval($result['expires'])){
//获取新Jsapi_ticket,更新缓存
$jsapi_ticket = getNewJsapi_ticket($access_token,$timestr);
return $jsapi_ticket;
}else{
return $result['ticket'];
}
}else{
$jsapi_ticket = getNewJsapi_ticket($access_token,$timestr);
return $jsapi_ticket;
}
}
//获取新Jsapi_ticket,更新缓存
function getNewJsapi_ticket($access_token,$timestr){
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$access_token}&type=jsapi";
$jsapi_ticket_Arr = curl_request($url);
$data = array();
//设置过期时间,预留200秒平滑过渡
$data['expires'] = intval($timestr) + intval($jsapi_ticket_Arr['expires_in']) - 200;
$data['time'] = $timestr;
$data['ticket'] = $jsapi_ticket_Arr['ticket'];
$jsonStr = json_encode($data);
$fp = fopen("jsapi_ticket.json", "w");
fwrite($fp, $jsonStr);
fclose($fp);
return $jsapi_ticket_Arr['ticket'];
}
//获取access_token,判断是否过期,没过期直接读取缓存
function getToken($appid,$appsecret){
//PHP创建access_token.json文件,将access_token 和生成时间expires 保存在其中,
//{"access_token":"xxxx","expires":1478799661}
$file = file_get_contents(dirname(__FILE__)."/access_token.json",true);
$result = json_decode($file,true);
$timestr = time();
if(array_key_exists('expires',$result)){
if ($timestr > intval($result['expires'])){
//获取新access_token,更新缓存
$access_token = getNewToken($appid,$appsecret,$timestr);
return $access_token;
}else{
return $result['access_token'];
}
}else{
$access_token = getNewToken($appid,$appsecret,$timestr);
return $access_token;
}
}
//获取新access_token,更新缓存
function getNewToken($appid,$appsecret,$timestr){
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
$access_token_Arr = curl_request($url);
$data = array();
//设置过期时间,预留200秒平滑过渡
$data['expires'] = intval($timestr) + intval($access_token_Arr['expires_in']) - 200;
$data['time'] = $timestr;
$data['access_token'] = $access_token_Arr['access_token'];
$jsonStr = json_encode($data);
$fp = fopen("access_token.json", "w");
fwrite($fp, $jsonStr);
fclose($fp);
return $access_token_Arr['access_token'];
}
/**
* curl Request函数
*/
function curl_request($url, $data = null)
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($curl);
curl_close($curl);
return json_decode($output,true);
}
/**
* 获取随机字符串
* @param int $randLength 长度
* @param int $addtime 是否加入当前时间戳
* @param int $includenumber 是否包含数字
* @return string
*/
function rand_str($randLength = 25, $addtime = 0, $includenumber = 1)
{
if ($includenumber) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHJKLMNPQEST123456789";
} else {
$chars = "abcdefghijklmnopqrstuvwxyz";
}
$len = strlen($chars);
$randStr = "";
for ($i = 0; $i < $randLength; $i++) {
$randStr .= $chars[mt_rand(0, $len - 1)];
}
$tokenvalue = $randStr;
if ($addtime) {
$tokenvalue = $randStr . time();
}
return $tokenvalue;
}
echo getSignature($myurl,$appid,$appsecret);
?>