Home > Backend Development > PHP Problem > How to get WeChat token and ticket in php and return signature

How to get WeChat token and ticket in php and return signature

醉折花枝作酒筹
Release: 2023-03-11 16:26:01
forward
3064 people have browsed it

When we want to know the WeChat token and ticket and return the signature, what should we do? Today we will introduce the method of obtaining WeChat token and ticket in PHP and returning the signature. You can refer to it if necessary.

How to get WeChat token and ticket in php and return signature

<?php
/*
 * 微信公众号后台里获取appId和appSecret,并在公众号后台=>安全中心=>IP白名单中设置当前页面服务器的IP,如果是负载均衡则需将每台子服务器IP都设置上,否则不能获取token
 */
class Jssdk {
    // 公众号的appId
    private $appId = &#39;wx98527950badbe995&#39;;
    // 公众号的appSecret
    private $appSecret = &#39;3482d6679db63ccacb67843f6ea8d9f9&#39;;
    
    // 获取签名等信息,本方法内容可做微信分享接口用
    public function getInfo() {
        // 获取最新可用ticket
        $jsapiTicket = $this->getJsApiTicket ();
        // 注意 URL 一定要动态获取,不能 hardcode.
        $protocol = (! empty ( $_SERVER [&#39;HTTPS&#39;] ) && $_SERVER [&#39;HTTPS&#39;] !== &#39;off&#39; || $_SERVER [&#39;SERVER_PORT&#39;] == 443) ? "https://" : "http://";
        // 获取当前页面的url
        // $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        // 如果方法作为接口,则无法将当前页面访问路径作为分享url,需要访问接口的前端页面通过 window.location.href 获取页面url传过来
        $url = $_POST [&#39;url&#39;] ? $_POST [&#39;url&#39;] : "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
        
        $timestamp = time ();
        $nonceStr  = $this->createNonceStr ();
        
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        
        $signature = sha1 ( $string );
        
        $signPackage = array (
                "appId"     => $this->appId,
                "nonceStr"  => $nonceStr,
                "timestamp" => $timestamp,
                "url"       => $url,
                "signature" => $signature,
                "rawString" => $string 
        );
        //如果是接口,这里则是 echo json_encode($signPackage);
        return $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;
    }
    // 获取ticket
    private function getJsApiTicket() {
        // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例,实际应存在数据库中
        $data = json_decode ( $this->get_php_file ( "jsapi_ticket.php" ) );
        //获取没过期的ticket,过期则重新获取
        if ($data->expire_time < time ()) {
            // 获取最新可用token,ticket需要通过token获取
            $accessToken = $this->getAccessToken ();
            // 如果是企业号用以下 URL 获取 ticket
            // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken";
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
            $res = json_decode ( $this->httpGet ( $url ) );
            $ticket = $res->ticket;
            if ($ticket) {
                //将有效时间设置成将来的7000秒内
                $data->expire_time = time () + 7000;
                $data->jsapi_ticket = $ticket;
                $this->set_php_file ( "jsapi_ticket.php", json_encode ( $data ) );
            }
        } else {
            $ticket = $data->jsapi_ticket;
        }
        
        return $ticket;
    }
    // 获取token
    private function getAccessToken() {
        // access_token 应该全局存储与更新,以下代码以写入到文件中做示例,实际应存在数据库中
        $data = json_decode ( $this->get_php_file ( "access_token.php" ) );
        //获取没过期的token,过期则重新获取
        if ($data->expire_time < time ()) {
            // 如果是企业号用以下URL获取access_token
            // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret";
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret";
            $res = json_decode ( $this->httpGet ( $url ) );
            $access_token = $res->access_token;
            if ($access_token) {
                //将有效时间设置成将来的7000秒内
                $data->expire_time = time () + 7000;
                $data->access_token = $access_token;
                $this->set_php_file ( "access_token.php", json_encode ( $data ) );
            }
        } else {
            $access_token = $data->access_token;
        }
        return $access_token;
    }
    // curl访问返回数据
    private function httpGet($url) {
        $curl = curl_init ();
        curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, true );
        curl_setopt ( $curl, CURLOPT_TIMEOUT, 500 );
        // 为保证第三方服务器与微信服务器之间数据传输的安全性,所有微信接口采用https方式调用,必须使用下面2行代码打开ssl安全校验。
        // 如果在部署过程中代码在此处验证失败,请到 http://curl.haxx.se/ca/cacert.pem 下载新的证书判别文件。
        curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, 1 );
        curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, 2 );//CURLOPT_SSL_VERIFYHOST 设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。注:公用名(Common Name)一般来讲就是填写将要申请SSL证书的域名 (domain)或子域名(sub domain)。 设置成 2,会检查公用名是否存在,并且是否与提供的主机名匹配。 在生产环境中,这个值应该是 2(默认值)
        curl_setopt ( $curl, CURLOPT_URL, $url );
        
        $res = curl_exec ( $curl );
        curl_close ( $curl );
        
        return $res;
    }
    // 读取文件
    private function get_php_file($filename) {
        return trim ( substr ( file_get_contents ( $filename ), 15 ) );
    }
    // 写入文件
    private function set_php_file($filename, $content) {
        $fp = fopen ( $filename, "w" );
        fwrite ( $fp, "<?php exit();?>" . $content );
        fclose ( $fp );
    }
}
Copy after login

access_token.php page, save the obtained token

<?php 
exit();
?>
{"access_token":"","expire_time":0}
Copy after login

jsapi_ticket.php page, save the obtained ticket

<?php
 exit();
 ?>
 {"jsapi_ticket":"","expire_time":0}
Copy after login

index. PHP page, front-end call page

<?php
/*
 * 前端页面,这里是直接包含了获取签名的页面,实际可将获取签名页面写成接口,前端通过ajax获取
*/
require_once "jssdk.php";
$jssdk = new Jssdk();
$info = $jssdk->getInfo();
?>
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
  
</body>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script>
  /*
   * 注意:
   * 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
   * 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
   * 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
   *
   * 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈:
   * 邮箱地址:weixin-open@qq.com
   * 邮件主题:【微信JS-SDK反馈】具体问题
   * 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
   */
  wx.config({
    debug: true,
    appId: &#39;<?php echo $info["appId"];?>&#39;,
    timestamp: <?php echo $info["timestamp"];?>,
    nonceStr: &#39;<?php echo $info["nonceStr"];?>&#39;,
    signature: &#39;<?php echo $info["signature"];?>&#39;,
    jsApiList: [
      // 所有要调用的 API 都要加到这个列表中
    ]
  });
  wx.ready(function () {
    // 在这里调用 API
  });
</script>
</html>
Copy after login

Recommended learning: php video tutorial

The above is the detailed content of How to get WeChat token and ticket in php and return signature. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
php
source:cnblogs.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template