微信公众号分享自定义标题、内容、图片 + php后台封装签名signature生成函数

php 微信公众号签名signature生成方法


因为要做网页的微信分享,分享的时候想自定义 分享标题 分享摘要 和分享缩略图,所以要用到微信公众号的jssdk,必然就牵扯到微信签名。

以thinkphp5为例,展示整个生成和使用的过程。
步骤:
1、获取微信access_token : 自定义函数 getWxAccessToken();
2、根据1 的access_token,获取ticket: 自定义函数 getWxTicket();
3、根据2 的ticket,自己拼装字符串,并生成签名sign: 自定义函数 makeWxSha1Sign();

后台php代码如下:

/**
     * 生成微信公众号签名
     * @param string url 前端微信分享页面的url全地址
     */
    public function getWxShareSign()
    {
        $signData = input('');
        if( !$signData['url'] ){
            $this->_error('参数错误');
        }
        $ticket = '';
        if($redis_ticket = cache::get('wx_share_ticket')){
            $ticket = $redis_ticket;
        }else{
            $access_token = $this->getWxAccessToken(); //获取微信access_token
            $ticket = $this->getWxTicket($access_token); //获取微信ticket
        }
        $signData['jsapi_ticket'] = $ticket;
        $signData['noncestr'] = 'abs1004';
        $signData['timestamp'] = time();
        $sign = $this->makeWxSha1Sign($signData); // 生成微信签名
        $signData['sign'] = $sign;

        $this->_success($signData); // jsapi_ticket, noncestr, timestamp, sign 都返回给前端,供前端页面微信验签使用
    }

    //生成 sha1 签名
    private function makeWxSha1Sign($arr){
        $str = "";
        //升序数组的键
        $keyArr = [];
        foreach ($arr as $k => $v) {
            array_push($keyArr,$k);
        }
        sort($keyArr);
        reset($keyArr);

        //升序数组的字符串拼接,删除signature
        foreach ($keyArr as $key => $value) {
            $linker = '';
            if($key!=0){
                $linker = '&';
            }
            $str .= $linker.$value.'='.$arr[$value];
        }
        log_result('wxshare signStr='.$str);

        //字符串SHA1
        $signature = sha1($str);
        return $signature;
    }

    //微信公众号 票据
    private function getWxTicket($access_token){
        $ticketUrl = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi';
        $ticketResp = file_get_contents($ticketUrl);
        if(!$ticketResp) $this->_error('ticket 获取失败');
        $ticketData = json_decode($ticketResp, true);
        if( isset($ticketData['ticket']) ){
            $ticket = $ticketData['ticket'];
            cache::set('wx_share_ticket',$ticket,7200);
            log_result('ticket='.$ticket);
            return $ticket;
        }else{
            $this->_error('ticket 解析错误');
        }

    }
    //微信公众号 token
    private function getWxAccessToken(){
        $tokeUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".config('wxgzh_appid')."&secret=".config('wxgzh_secret');
        $tokenResp = file_get_contents($tokeUrl);
        if(!$tokenResp) $this->_error('token 服务器返回失败');
        $tokenData = json_decode($tokenResp, true);
        if( !isset($tokenData['access_token']) ) $this->_error($tokenData['errmsg']);
        return $tokenData['access_token'];
    }
    
// 成功返回封装  json格式的数据给前端
protected function _success ($data=null, $info='操作成功', $status=1000)
	{
		$result = array(
			'status' => $status,
			'msg'	=>	$info,
			'data'	=>	$data,
		);
		die( json_encode($result) );
	}
// 失败返回封装  json格式的数据给前端	
protected function _error ($info='系统错误', $status=-1004)
	{
		$result = array(
			'status' => $status,
			'msg'	=>	$info,
		);
		die( json_encode($result) );
	}

前端代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge" >
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" >
    <meta name="description" content="正方形口腔 ">
    <meta name="keywords" content="正方形口腔 ">
    <title>正方形口腔 - 送牙币</title>
    <link rel="stylesheet" href="/res/css/bootstrap.css">
    <link rel="stylesheet" href="/res/css/font-awesome.css">
    <script src="/res/js/jquery.min.js"></script>
    <script src="/res/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
    <style>

        body{
            background:#fc471e url("/res/img/share/bg@2x.png") no-repeat 100% 100%;
            font-weight: 200;
        }
        #content {
            background: transparent;
        }
        ::-webkit-input-placeholder { /* WebKit browsers */
            color:    #F06D4A;
        }
        :-moz-placeholder { /* Mozilla Firefox 4 to 18 */
            color:    #F06D4A;
        }
        ::-moz-placeholder { /* Mozilla Firefox 19+ */
            color:    #F06D4A;
        }
        :-ms-input-placeholder { /* Internet Explorer 10+ */
            color:    #F06D4A;
        }
        header{
            height: 48px;
            width:100%;
            background: #fff;
            color: #333;
            text-align: center;
            line-height: 48px;
            font-size: 17px;
        }
        .quan {
            vertical-align: middle;
            border: 0;
            width: 100%;
            height: auto;
        }

        .form-control{
            /*height: 48px;*/
            border:none;
            font-size: 14px;
            padding-right: 0;
        }


        input{
        }
        .abs-input-box{
            width: 90%;
            margin: 1px 5%;
        }
        .btn-code{
            height: 38px;
            padding: 0;
            font-weight: 200;
            width:100%;
            background: #fad142;
        }
        .input-mobile-box{
            border-radius: 5px;
            background: #fff;
            background-image: url('/res/img/share/icon_username@2x.png');
            background-repeat: no-repeat;
            background-size: 20px 20px;
            background-position: 8px 8px;
            overflow: hidden;
            height: 40px;
            line-height: 40px;
            padding: 0 0;
        }
        .input-mobile{
            height: 30px;
            width: 100%;
            border:none;
            line-height: 30px;
            color: #262626;
            margin-left: 40px;
            font-weight: 300;
            margin-top:5px ;
        }
        .input-code-box{
            border-radius: 5px;
            background: #fff;
            width:60%;
            float:left;
            background-image: url('/res/img/share/icon_yanzhengma@2x.png');
            background-repeat: no-repeat;
            background-size: 20px 20px;
            background-position: 8px 8px;
            overflow: hidden;
            height: 38px;
            line-height: 38px;
        }
        .input-code{
            color: #262626;
            width: 100%;
            border:none;
            height: 30px;
            line-height: 30px;
            margin-top: 4px;
            margin-left: 40px;
            font-weight: 300;
            padding: 0 0;
        }

        .btn-quan{
            height: 48px;
            border-radius: 5px;
            background: #feec34;
            width:100%;
            font-weight: 400;
            font-size: 18px;
        }

        .mt-35{
            margin-top: 35px;
        }
        .btn.focus, .btn:focus, .btn:hover{
            color:inherit;
        }

        .bg-gray{
            background: #999;
            color:#f3f3f3;
        }
        .bg-red{
            background: #fa6262;
        }
        .color-white{
            color:#fff;
        }
        .color-red{
            color:rgb(219,43,19);
        }

        .test-before:before{
            content: 'abs';
        }
        td{line-height: 180%;}
    </style>
</head>
<body>

    <div class="container">
        <!-- 优惠券券 -->
        <div class="row mt-35">
                <img class="quan"  src="/res/img/share/pic_lihe@2x.png" alt="正方形口腔-分享领券">
        </div>

        <!-- 手机号 -->
        <div class="row ">
            <div class="abs-input-box">
                <form role="form">
                    <div class="form-group">
                        <div class="input-mobile-box">
                            <input type="text" required class="input-mobile" id="mobile" placeholder="请输入11位中国大陆手机号">
                        </div>
                    </div>
                    <div class="form-group">
                        <div style="height: 40px;">
                            <div class="input-code-box" >
                                <input type="text" required class=" input-code" id="code" placeholder="输入短信验证码">
                            </div >
                            <div style="width:30%;float:right;height:40px;">
                                <button  class="btn btn-code color-red" type="button" id="btn_get_code">获取验证码</button>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <button type="button" class=" btn btn-quan color-red" id="btn_download">下载领币</button>
                    </div>
                </form>
            </div>
        </div>
        <div class="mt-35 color-white">

            <p>
                活动规则:<br />
            </p>
            <table>
                <tr>
                    <td style="vertical-align: top">1、</td>
                    <td>活动时间:2018年11月1日-2019年6月30日。</td>
                </tr>
                <tr>
                    <td style="vertical-align: top">2、</td>
                    <td>已在正方形口腔建档的用户(以下简称“老用户”)可以通过此链接邀请好友下载注册正方形口腔APP,并参照以下规则获得相应牙币:</td>
                </tr>
                <tr>
                    <td style="vertical-align: top">a、</td>
                    <td>老用户每邀请一名未在正方形口腔建档的用户(以下简称“新用户”)注册登录正方形APP后,老用户即可获得50牙币;</td>
                </tr>
                <tr>
                    <td style="vertical-align: top">b、</td>
                    <td>被邀请的新用户注册登录正方形口腔APP后,即可获得100牙币。</td>
                </tr>
                <tr>
                    <td style="vertical-align: top">3、</td>
                    <td>1牙币=1元人民币,牙币可用于诊费支付及礼品兑换。</td>
                </tr>
                <tr>
                    <td style="vertical-align: top">4、</td>
                    <td>活动过程中凡是以恶意手段(包括但不限于作弊、攻击系统等)参与的用户,正方形口腔有权利终止其参与活动并取消获取牙币的资格。</td>
                </tr>
                <tr>
                    <td style="vertical-align: top">5、</td>
                    <td>在法律范围内正方形口腔拥有本活动解释权。</td>
                </tr>
            </table>

        </div>

    </div>
</body>
<script>
    var domain = "{$Think.config.site_url}"; // 域名 https://www.zhipur.com
    var curUrl = window.location.href;

    //微信设置
    var shareLink = curUrl;
    var shareIcon = domain+"/logo.png";
    var shareDesc = "微信分享内容摘要";
    
    // ajax请求后台接口,获取微信签名
    $.ajax({
        url: domain+"/api/webview/getWxShareSign",
        data:{
            url: curUrl
        },
        type: 'POST',
        dataType: 'json',
        success: function (res) {
            if(res.status===1000){
                wx.config({
                    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                    appId: 'wx112312312321312312', // 必填,换成你公众号里的appid
                    timestamp: res.data.timestamp, // 必填,生成签名的时间戳
                    nonceStr: res.data.noncestr, // 必填,生成签名的随机串
                    signature: res.data.sign,// 必填,签名
                    jsApiList: ['onMenuShareTimeline','onMenuShareAppMessage'] // 必填,需要使用的JS接口列表
                });
            }else{
                console.log(res.msg);
            }
        },
        error: function (e) {
            console.log(e);
        }
    });
    wx.ready(function(){
        wx.onMenuShareAppMessage({
            title: '微信分享标题文字', // 分享标题
            desc: shareDesc, // 分享描述
            link: shareLink, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
            imgUrl: shareIcon, // 分享图标
            success: function () {
                // 用户点击了分享后执行的回调函数
                console.log('用户点击了分享');
            }
        });

    });
    wx.error(function(res){
        console.log('wx jsapi fail');
    });

</script>
</html>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值