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
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
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?
过去多啦不再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>
仅有的幸福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
给我你的怀抱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
淡淡烟草味2017-05-16 17:25:32
Check out my answer from another person:
/q/1010000002502269/a-1020000002549180X2X
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.
阿神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);