侧边栏壁纸
博主昵称
梦之中小俊

以前高中时,羡慕大学考试只要及格就行;现在大学了,怀念高中考试及不及格都行??

微信JSSDK-php-签名实现

梦之中小俊
2021-07-15 / 0 评论 / 267 阅读 / 推送成功!
  • 官方文档(附录1-JS-SDK使用权限签名算法)

    生成签名的主要步骤

    1. 获取access_token
    2. 通过第一步获取的access_token去获取jsapi_ticket
    3. 利用签名算法生成签名
    4. 前端通过调用生成签名的接口获得签名等信息

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秒。
3

打赏

评论 (0)

OωO
  • ::(呵呵)
  • ::(哈哈)
  • ::(吐舌)
  • ::(太开心)
  • ::(笑眼)
  • ::(花心)
  • ::(小乖)
  • ::(乖)
  • ::(捂嘴笑)
  • ::(滑稽)
  • ::(你懂的)
  • ::(不高兴)
  • ::(怒)
  • ::(汗)
  • ::(黑线)
  • ::(泪)
  • ::(真棒)
  • ::(喷)
  • ::(惊哭)
  • ::(阴险)
  • ::(鄙视)
  • ::(酷)
  • ::(啊)
  • ::(狂汗)
  • ::(what)
  • ::(疑问)
  • ::(酸爽)
  • ::(呀咩爹)
  • ::(委屈)
  • ::(惊讶)
  • ::(睡觉)
  • ::(笑尿)
  • ::(挖鼻)
  • ::(吐)
  • ::(犀利)
  • ::(小红脸)
  • ::(懒得理)
  • ::(勉强)
  • ::(爱心)
  • ::(心碎)
  • ::(玫瑰)
  • ::(礼物)
  • ::(彩虹)
  • ::(太阳)
  • ::(星星月亮)
  • ::(钱币)
  • ::(茶杯)
  • ::(蛋糕)
  • ::(大拇指)
  • ::(胜利)
  • ::(haha)
  • ::(OK)
  • ::(沙发)
  • ::(手纸)
  • ::(香蕉)
  • ::(便便)
  • ::(药丸)
  • ::(红领巾)
  • ::(蜡烛)
  • ::(音乐)
  • ::(灯泡)
  • ::(开心)
  • ::(钱)
  • ::(咦)
  • ::(呼)
  • ::(冷)
  • ::(生气)
  • ::(弱)
  • ::(狗头)
泡泡
阿鲁
颜文字
取消
  1. 头像
    6767 Lv.1
    iPhone · Safari
    沙发

    画图

    回复
  2. 头像
    6767 Lv.1
    Windows 10 · Google Chrome
    板凳

    表情

    回复
  3. 头像
    透露 Lv.2
    Android · QQ Browser
    第30楼

    649494848

    回复