搜尋

首頁  >  問答  >  主體

nginx - 微信JSSDK,config執行的時候報錯:invalid signature

1,計算出來的簽章與微信提供的沙箱一致:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
2,嘗試使用了兩種方法解決,但是還是同樣錯誤:1),從本地把URL傳到服務端,透過ajax獲取服務端的json數據,然後填寫wx.config的內容;2),從服務端獲取本次訪問的連結
3,採用nginx做反向域名代理,但已經針對upstream進行了處理
結論:懷疑微信的JSSDK存在bug

#
给我你的怀抱给我你的怀抱2792 天前1074

全部回覆(8)我來回復

  • ringa_lee

    ringa_lee2017-05-16 17:25:32

    可能要檢查
    1) 你是否有在伺服器全域快取微信的jsticket的,一個新的jsticket獲得後會刷新掉原來的jsticket(也包括access_token)
    2) url是否一致,包括query string等
    3) nonceStr和timestamp是否與簽名時一致

    回覆
    0
  • PHP中文网

    PHP中文网2017-05-16 17:25:32

    我也懷疑有bug, 在android下invalid signature , 在ios下是正確的。而且在官方調試頁面是透過的, 不知道樓主現在解決了沒有?

    回覆
    0
  • 过去多啦不再A梦

    过去多啦不再A梦2017-05-16 17:25:32

    也許是url传入的问题,建议wx.config是透過後台生成,然後寫到前台的。

    比如我的

    import time
    import random
    import string
    import hashlib
    import urllib2
    import json
    
    from sae.kvdb import Client
    
    
    kvdb = Client()
    
    
    class WXSDK(object):
        httpHandler = urllib2.HTTPHandler()
        httpsHandler = urllib2.HTTPSHandler()
        opener = urllib2.build_opener(httpHandler, httpsHandler)
        urllib2.install_opener(opener)
    
        JSAPI_TICKET_URL = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi'
        ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}'
    
        def __init__(self, app_id, app_secret, url=None):
            self.app_id = app_id
            self.app_secret = app_secret
            self.url = url
    
    
        def __sendRequest(self, url):
            return json.loads(urllib2.urlopen(url).read())
    
        def __get_access_token(self):
            data = kvdb.get('access_token_key') or {'expire_time': 0}
            now = self.__get_time()
            if data['expire_time'] < now:
                data['expire_time'] = now + 7000
                res = self.__sendRequest(
                    self.ACCESS_TOKEN_URL.format(self.app_id, self.app_secret))
                data['access_token'] = res['access_token']
                kvdb.set('access_token_key', data)
                return res['access_token']
            else:
                return data['access_token']
    
        def __get_jsapi_ticket(self):
            data = kvdb.get('jsapi_token_key') or {'expire_time': 0}
            now = self.__get_time()
            if data['expire_time'] < now:
                data['expire_time'] = now + 7000
                access_token = self.__get_access_token()
                res = self.__sendRequest(
                    self.JSAPI_TICKET_URL.format(access_token))
                data['jsapi_ticket'] = res['ticket']
                kvdb.set('jsapi_token_key', data)
                return res['ticket']
            else:
                return data['jsapi_ticket']
    
        def __get_time(self):
            return int(time.time())
    
        def __create_nonce_str(self):
            return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(15))
    
        def get_sign_package(self):
            options = {
                'nonceStr': self.__create_nonce_str(),
                'jsapi_ticket': self.__get_jsapi_ticket(),
                'timestamp': self.__get_time(),
                'url': self.url
            }
            options['signature'] = Sign(options.copy()).sign()
            options['app_id'] = self.app_id
            return options
    
    
    class Sign(object):
        def __init__(self, options):
            self.ret = options
    
        def sign(self):
            signature = '&'.join(['%s=%s' % (key.lower(), self.ret[key])
                                  for key in sorted(self.ret)])
            return hashlib.sha1(signature).hexdigest()
    
    

    然後

    @card.route("/")
    def index():
        url = request.base_url
        if len(request.args) > 0:
            url = url + "?" + urllib.urlencode(request.args)
        wx.url = url
        signature_data = wx.get_sign_package()
        return render_template("card/index.html", wx=signature_data)
    

    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> wx.config({ appId: '{{wx.app_id}}', timestamp: {{wx.timestamp}}, nonceStr: '{{wx.nonceStr}}', signature: '{{wx.signature}}', jsApiList: [ 'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo' ] }); </script>

    回覆
    0
  • 仅有的幸福

    仅有的幸福2017-05-16 17:25:32

    樓主的問題解決了嗎,我也是同樣的問題,反正對比的接口,也用微信的測試工具測試了,就是一直出invalid signature

    回覆
    0
  • 给我你的怀抱

    给我你的怀抱2017-05-16 17:25:32

    簽章和官方的一樣、 URL也是透過location.href.split('#')[0]取得的。 。 也是一直提示 config:invalid signature 公眾號的JS介面安全網域也是配置OK,但不行。 。 求大神幫助、
    測試網址:http://weixin.zhjckx.com/ApiWeiXin/JsSdk

    回覆
    0
  • 淡淡烟草味

    淡淡烟草味2017-05-16 17:25:32

    清看我的另一人回答:

    /q/1010000002502269/a-1020000002549180X2X

    回覆
    0
  • PHP中文网

    PHP中文网2017-05-16 17:25:32

    我遇到的情況是,在產生簽章時取得目前url時,用了laravel框架的URL:full()方法。結果這個方法會把url中的querystring的順序重排。例如你造訪時的url是

    http://test.com?x=1&a=2
    

    ,用URL:full()得到的結果是

    http://test.com?a=2&x=1
    

    改成老實實用微信官方例子中的:

    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    

    就OK了。

    回覆
    0
  • 阿神

    阿神2017-05-16 17:25:32

    親自修改的,測試ok的。原因是因為官方裡的httpGet函數不能用。

    講 jssdk.php 裡的這兩句話

    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);
    
    改为 
    
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);// 这里改为false, 可以请求https的网页
    //curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, true);

    回覆
    0
  • 取消回覆