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
可能需要检查 1) 你是否有在服务器全局缓存微信的jsticket的,一个新的jsticket获得后会刷新掉原来的jsticket(也包括access_token) 2) url是否一致,包括query string等 3) nonceStr和timestamp是否与签名时一致
我也怀疑有bug, 在android下invalid signature , 在ios下是正确的。而且在官方调试页面是通过的, 不知道楼主现在解决了没有?
也许是url传入的问题,建议wx.config是通过后台生成,然后写到前台的。
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>
楼主的问题解决了吗,我也是同样的问题,反正对比的接口,也用微信的测试工具测试了,就是一直出invalid signature
签名和官方的一样、 URL也是通过location.href.split('#')[0]获取的。。 也是一直提示 config:invalid signature 公众号的JS接口安全域名也是配置OK,就是不行。。 求大神帮助、 测试地址:http://weixin.zhjckx.com/ApiWeiXin/JsSdk
清看我的另一人回答:
/q/1010000002502269/a-1020000002549180X2X
我遇到的情况是,在生成签名时获取当前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了。
亲自修改的,测试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);
可能需要检查
1) 你是否有在服务器全局缓存微信的jsticket的,一个新的jsticket获得后会刷新掉原来的jsticket(也包括access_token)
2) url是否一致,包括query string等
3) nonceStr和timestamp是否与签名时一致
我也怀疑有bug, 在android下invalid signature , 在ios下是正确的。而且在官方调试页面是通过的, 不知道楼主现在解决了没有?
也许是
url
传入的问题,建议wx.config
是通过后台生成,然后写到前台的。比如我的
然后
楼主的问题解决了吗,我也是同样的问题,反正对比的接口,也用微信的测试工具测试了,就是一直出invalid signature
签名和官方的一样、 URL也是通过location.href.split('#')[0]获取的。。 也是一直提示 config:invalid signature 公众号的JS接口安全域名也是配置OK,就是不行。。 求大神帮助、
测试地址:http://weixin.zhjckx.com/ApiWeiXin/JsSdk
清看我的另一人回答:
/q/1010000002502269/a-1020000002549180X2X
我遇到的情况是,在生成签名时获取当前url时,用了laravel框架的URL:full()方法。结果这个方法会把url中的querystring的顺序重排。比如你访问时的url是
,用URL:full()获取的结果是
改成老老实实用微信官方例子中的:
就OK了。
亲自修改的,测试ok的。原因是因为官方里的httpGet函数不能用。
讲 jssdk.php 里的这两句