>  기사  >  백엔드 개발  >  PHP로 WeChat 토큰과 티켓을 받고 서명을 반환하는 방법

PHP로 WeChat 토큰과 티켓을 받고 서명을 반환하는 방법

醉折花枝作酒筹
醉折花枝作酒筹앞으로
2021-07-16 15:27:053014검색

WeChat 토큰과 티켓을 알고 서명을 돌려주고 싶을 때는 어떻게 해야 하나요? 오늘은 위챗 토큰과 티켓을 PHP로 받고 서명을 돌려주는 방법을 소개하겠습니다. 필요하시면 참고하시면 됩니다.

PHP로 WeChat 토큰과 티켓을 받고 서명을 반환하는 방법

<?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 );
    }
}

access_token.php 페이지, 획득한 토큰 저장

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

jsapi_ticket.php 페이지, 획득한 티켓 저장

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

index.php 페이지, 프론트 엔드 호출 페이지

<?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>

추천 학습: php 비디오 튜토리얼

위 내용은 PHP로 WeChat 토큰과 티켓을 받고 서명을 반환하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제