search

Home  >  Q&A  >  body text

nginx - WeChat JSSDK, an error is reported when config is executed: invalid signature

1, the calculated signature is consistent with the sandbox provided by WeChat: http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
2. Tried to use two methods to solve the problem, but still got the same error: 1), pass the URL from the local to the server, get the json data of the server through ajax, and then fill in the content of wx.config; 2), get it from the server Link to this visit
3. Use nginx as reverse domain name proxy, but it has been processed for upstream
Conclusion: It is suspected that WeChat’s JSSDK has a bug

给我你的怀抱给我你的怀抱2790 days ago1071

reply all(8)I'll reply

  • ringa_lee

    ringa_lee2017-05-16 17:25:32

    May need to be checked
    1) Do you cache WeChat’s jsticket globally on the server? After a new jsticket is obtained, the original jsticket (including access_token) will be refreshed
    2) Whether the url is consistent, including query string, etc.
    3) Whether nonceStr and timestamp are consistent with the signature

    reply
    0
  • PHP中文网

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

    I also suspect there is a bug. The invalid signature is invalid under android, but it is correct under ios. And it is passed on the official debugging page. I wonder if the original poster has solved it now?

    reply
    0
  • 过去多啦不再A梦

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

    Perhaps url传入的问题,建议wx.config is generated through the background and then written to the foreground.

    Like mine

    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()
    
    

    Then

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

    reply
    0
  • 仅有的幸福

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

    Has the poster’s problem been solved? I have the same problem. Anyway, I also tested the interface for comparison with WeChat’s testing tool, but it keeps showing invalid signature

    reply
    0
  • 给我你的怀抱

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

    The signature is the same as the official one, and the URL is also obtained through location.href.split('#')[0]. . It also keeps prompting config:invalid signature. The JS interface security domain name of the official account is also configured OK, but not working. . Ask God for help,
    Test address: http://weixin.zhjckx.com/ApiWeiXin/JsSdk

    reply
    0
  • 淡淡烟草味

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

    Check out my answer from another person:

    /q/1010000002502269/a-1020000002549180X2X

    reply
    0
  • PHP中文网

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

    The situation I encountered was that when obtaining the current URL when generating a signature, the URL:full() method of the laravel framework was used. As a result, this method will rearrange the order of the query string in the URL. For example, the url when you visit is

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

    , the result obtained by using URL:full() is

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

    Changed to the honest and practical WeChat official example:

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

    It’s OK.

    reply
    0
  • 阿神

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

    I modified it myself and tested it ok. The reason is because the official httpGet function cannot be used.

    Tell me these two sentences in 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);

    reply
    0
  • Cancelreply