调用扫一扫功能有几个步骤
简单而言:
1 获取accesstoken
2 获取jsapi_ticket
3 生成签名signature
调用wx.config wx.ready wx.error
三个function
=======我个人的代码在最后面,只是部分代码。具体的需要你们自己写,我用的是LaneWechat
(1和2都需要自己把它存储起来,ticket的调用次数比较少,所以更要注意,记住要写一个中转器自动检查更新这两个数据,而不是主动请求的时候才去生成新的凭据,否则在会出现延迟,页面出现错误,需要再次刷新才正常)
============================详细介绍:
在这里要说的是,我之前提示的是invaild signature 结果用官方的接口调试工具发现我生成的加密数据和官方生成的不同,调试工具:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
结果发现,是因为我的timestramp 和 noncsrt 用的不是同一个,他们分别执行了两次,对不上号所以出错了。大家要注意
成功返回如下JSON:
{ "errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }
获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。
签名算法
签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。
即signature=sha1(string1)。 示例:
步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1:
jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value
步骤2. 对string1进行sha1签名,得到signature:
0f9de62fce790f9a083d5c99e95740ceb90c27ed
注意事项
class JsapiTicket{
public static function getJsapiTicket(){
$jsapi_ticket = self::_checkJsapiTicket();
if($jsapi_ticket === false){
$jsapi_ticket = self::_getJsapiTicket();
}
return $jsapi_ticket['ticket'];
}
private static function _getJsapiTicket(){
$accessToken=AccessToken::getAccessToken();//获取access_token
//通过获取的accessToken请求 jsapi Ticket
//请求地址: https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
//GET方式请求
// print_r('get_accesstoken====>'.$accessToken);
$ticket_url='https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$accessToken.'&type=jsapi';
$jsapi_ticket = Curl::callWebServer($ticket_url, '', 'GET');
// print_r('JsapiTicket:====>>>'.$jsapi_ticket);
$jsapi_ticket['time'] = time();//设置时间戳
$jsapi_ticketJson = json_encode($jsapi_ticket);
$f = fopen('jsapi_ticket', 'w+');//将ticket保存下来。它也是有效期为7200S,而且接口的调用次数比accesstoken少
fwrite($f, $jsapi_ticketJson);
fclose($f);
// print_r('jsapi_ticket====>'.$jsapi_ticketJson);
return $jsapi_ticketJson;
}
/**
* @descrpition 检测微信ticket是否过期
*
* @return bool
*/
private static function _checkJsapiTicket(){
$data = file_get_contents('jsapi_ticket');
//print_r('从文件中读取的accesstoken,data是 :'.$data);
$jsapi_ticket['value'] = $data;
if(!empty($jsapi_ticket['value'])){
$jsapi_ticket = json_decode($jsapi_ticket['value'], true);
if(time() - $jsapi_ticket['time'] < $jsapi_ticket['expires_in']-200){//200为缓冲期
return $jsapi_ticket;
}
}
return false;//无论是ACCESSTOKEN过期了还是没有ACCESSTOKEN,都返回FALSE
}
}
$randNumber=getRandChar(10);//随机字符串,这个是必要的
$curtime=time();//生成一个时间戳
function ticket(){
$ticket=JsapiTicket::getJsapiTicket();//获取ticket
//print_r($ticket);
return $ticket;
}
function getRandChar($length){
$str = null;
$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
$max = strlen($strPol)-1;
for($i=0;$i<$length;$i++){
$str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数
}
return $str;
}
function getSignature(){
//获取SHA1加密后的字符串(官方有个加密检测工具,如果生成的最后数据跟你的生成的不一样,就说明是错的,其中有可能错的就是,你生成了两次的随机数或者两次的时间戳,所以务必确认你生成的参数和你提交的参数是相同的)
global $randNumber;
global $curtime;
$str="jsapi_ticket=".ticket()."&noncestr=".$randNumber."×tamp=".$curtime."&url=http://weixin.ittun.com/huayuanWechat/saomiao.php";
//echo $str;
$signature=sha1($str);
return $signature;
//return $str;
}
});
测试完成后再wx.config方法中的debug参数设置为false,这样alert窗口的提示就不会弹出来了