-
官方文档(附录1-JS-SDK使用权限签名算法)
生成签名的主要步骤
- 获取access_token
- 通过第一步获取的access_token去获取jsapi_ticket
- 利用签名算法生成签名
- 前端通过调用生成签名的接口获得签名等信息
A. 获取access_token
access_token是采用http GET方式获取的($a,$s分别为你的appid和appsecret)
url: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$a&secret=$s
通过开发者工具中的接口调试工具,可以测试你能否正确获取到access_token,如果返回的提示是++Request successful++,则说明能成功获取access_token
// 成功获取后,微信会返回一个access_token和一个过期时间expires_in
{
"access_token": "XXX",
"expires_in": 7200
}
// 失败时则返回errcode和errmsg
{
"errcode": 40125,
"errmsg": ""
}
获取access_token之后,需要把它缓存起来,可以通过把微信返回的信息保存为文件,也可以通过把信息保存到数据库,我是通过把信息存到数据库的
PHP 代码如下:
public function getAccessToken() {
// access_token 应该全局存储与更新
// 获取数据库中的access_token
$token = M('accesstoken')->limit(1)->find();
// 如果数据库存在token
if ($token) {
// 格式化数据库的timestamp
$time = strtotime($token['time']);
}
// accessToken过期或不存在时
if($time + $token['expiresIn'] < time() || $token['accessToken'] == NULL){
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".C('WxPayConf_pub.APPID')."&secret=".C('WxPayConf_pub.APPSECRET');
// 微信返回的信息
$returnData = json_decode($this->httpGet($url));
// 组装数据
$resData['accessToken'] = $returnData->access_token;
$resData['expiresIn'] = $returnData->expires_in;
$resData['time'] = date("Y-m-d H:i",time());
// 把数据存进数据库
M('accesstoken')->where(array('id' => $token['id']))->save($resData);
$res = $resData;
}else{
$res = $token;
}
return $res;
}
private function httpGet($url) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
curl_setopt($curl, CURLOPT_TIMEOUT, 500 );
curl_setopt($curl, CURLOPT_URL, $url );
$res = curl_exec($curl);
curl_close($curl);
return $res;
}
B. 获取api_ticket
api_ticket也是采用http GET方式获取的($token为第一步获取的access_token)
url: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$token&type=jsapi
public function getJsApiTicket($accessToken) {
// jsapi_ticket 应该全局存储与更新
// 获取数据库中的jsapi_ticket
$ticket = M('jsticket')->limit(1)->find();
$paseTime = strtotime($ticket['time']);
// 如果ticket失效
if($time + $token['expiresIn'] < time() || $ticket['ticket'] == NULL){
$url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&&type=jsapi";
// 微信返回的信息
$returnData = json_decode($this->httpGet($url));
// 组装数据
$resData['ticket'] = $returnData->ticket;
$resData['expiresIn'] = $returnData ->expires_in;
$resData['time'] = date("Y-m-d H:i",time());
$resData['errcode'] = $returnData->errcode;
// 把数据存进数据库
M('jsticket')->where(array('id' => $ticket['id']))->save($resData);
$res = $resData;
}else{
$res = $ticket;
}
return $res;
}
C. 利用签名算法实现签名
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
// 获取签名
public function getSignPackage() {
// 获取token
$token = $this->getAccessToken();
// 获取ticket
$ticketList = $this->getJsApiTicket($token['accessToken']);
$ticket = $ticketList['ticket'];
// 该URL为使用JSSDK接口的URL
$url = $_GET['url'];
if (!$url) {
$url = 'http://xxx.xxx.com/index/index.html';
}
// 时间戳
$timestamp = time();
// 随机字符串
$nonceStr = $this->createNoncestr();
// 这里参数的顺序要按照 key 值 ASCII 码升序排序 j -> n -> t -> u
$string = "jsapi_ticket=$ticket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
$signature = sha1($string);
$signPackage = array (
"appId" => C('WxPayConf_pub.APPID'),
"nonceStr" => $nonceStr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $signature,
"rawString" => $string,
"ticket" => $ticket,
"token" => $token['accessToken']
);
// 提供数据给前端
$this->ajaxReturn(array('status' => true, 'data' => $signPackage));
}
// 创建随机字符串
private function createNoncestr($length = 16) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str = "";
for($i = 0; $i < $length; $i ++) {
$str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 );
}
return $str;
}
本文共 个字数,平均阅读时长 ≈ 分钟,您已阅读:0时0分0秒。
649494848