android user-agent iso-8859-1,微信网页授权,错误40163,ios正确,安卓错误?
2018-07-18:一年時間過去了,我又回來填自己挖的坑了!!
2017年7月,我遇到了這個問題,當時在這里提了問,后來又跟蹤了兩天,也沒徹底搞懂,反正時好時壞,,后來自己主要精力放在H5+開發上,就不怎么關心公眾號這塊了;
2018年7月,我又帶著python重回公眾號,又遇到了這個問題,這次繞不過去了,一年過去了,網上搜索一下,問這個問題的人還是很多,而且也沒有真正解決這個問題,
其實這個問題也不復雜,總結起來說,就是“點擊公眾號菜單產生兩次請求”,導致code被用了兩次,但是因為微信官方的文檔沒有相關內容,大家也都用自己的方式解決,我的解答應該也只是其中一種吧。
有人說:“后來發現只要加個屬性就不會有這個問題了。
https://open.weixin.qq.com/co...connect_redirect=1#wechat_redirect
&connect_redirect=1 這個參數”
!很可惜,這條加上去,對我一點也不起作用!
又仔細閱讀微信官方的文檔https://mp.weixin.qq.com/wiki...
這里有
appid
redirect_uri
response_type
scope
state
wechat_redirect
的作用說明,但是并沒有上面提到的connect_redirect,
提到了一個state的參數,這個是干嘛用的呢?
/
state 否 重定向后會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128字節
/
測試的時候發現,在訪問https://open.weixin.qq.com/co...,無論state填什么,獲取code的時候,這個字段會原樣返回過來,好就用它來解決。
既然這個參數會被原樣返回過來,那我就利用它作為一個令牌,發送之前先生成一個隨機數,然后保存到一個全局變量里,在redirect_uri頁面的接收到這個隨機數,跟全局變量對比一下,如果一樣,就把這個令牌改掉,這樣第二次訪問的時候,這個令牌就失效了,就pass掉這個請求,避免了被2次訪問的情況。
PS.
純php沒有全局變量,用一些框架應該就會有,或者寫到session或者緩存都行;
我是在django里開發的,所以就直接搞了個全局變量,簡單粗暴。
我是python初學者,代碼寫得比較拖沓啰嗦,見諒。
有人說是微信內置瀏覽器的問題,也有人說是nginx的問題,我覺得應該不是nginx,因為這次用python用的是django內置的服務器,也同樣情況。這個問題在蘋果手機上好像就沒有,主要是在安卓版微信上有,因為自己已經不用蘋果手機了,所以也沒有做測試。
最后,上代碼:
我的開發環境:
python 3.5.3
django 2.0.7
view.py代碼如下:
import json
import random
import requests
#全局變量
APP_ID = '公眾號ID'
App_SEC = '公眾號SEC'
RADOM_STATE = ""
def oauth(request):
global RADOM_STATE
_code = request.GET
#1 第一步,拿到code
oauth_state = _code['state']
oauth_code = _code['code']
oauth_info_json = {
'oauth_state' : oauth_state,
'oauth_code' : oauth_code
}
#print("=====>" + json.dumps(oauth_info_json))
print(oauth_state) #本次拿到的隨機數令牌
print(RADOM_STATE) #全局變量里保存的跳轉之前生成的隨機數令牌
#比較本次state和全局隨機數令牌是否一致,不一致,說明是第二次訪問,丟棄
if RADOM_STATE != oauth_state:
pass
else:
#一致,重新生成隨機數令牌,防止第二次訪問造成code失效
RADOM_STATE = str(random.randint(1000, 9999))
# print(RADOM_STATE)
# 2 第二步, 換取access_token
url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid={}&secret={}&code={}&grant_type=authorization_code'.format(APP_ID, App_SEC, oauth_code)
print(url)
oauth_access_token = requests.get(url)
print("=====>" + oauth_access_token.text)
re_json_str = oauth_access_token.text
# print(type(re_json_str), re_json_str)
re_json = json.loads(re_json_str)
# print(type(re_json), re_json)
# 3 第三步,拿到用戶信息
try:
url = 'https://api.weixin.qq.com/sns/userinfo?access_token={}&openid={}&lang=zh_CN'.format(re_json['access_token'], re_json['openid'])
print(url)
user_info = requests.get(url)
#print(user_info.encoding)
#print(user_info.text.encode("iso-8859-1").decode('utf8'))
user_info_json_str = user_info.text.encode("iso-8859-1").decode('utf8') #微信傳過來的中文使用的iso8859編碼,為了在模板里能顯示出來,要轉換成utf8編碼
# print(type(user_info_json_str), user_info_json_str)
user_info_json = json.loads(user_info_json_str)
# print(type(user_info_json), user_info_json)
except Exception as e:
print(e)
#把數據給html模板,其實oauth_info_json沒必要傳了,
#只需要user_info_json就夠了,這里只是為了演示!
#或者提取了user_info之后做各種業務邏輯操作都可以!
content = {
'oauth_info': oauth_info_json, #oauth_info_json
'user_info': user_info_json #user_info_json
}
return render(request, 'user_info.html', content)
def user_info(request):
global RADOM_STATE
REDIRECT_URI = "http://www.xxxxxxxxx.cn/weixin/oauth/" #跳轉的地址
SCOPE = "snsapi_userinfo"
STATE = str(random.randint(1000,9999)) #生成隨機數
RADOM_STATE = STATE #隨機數給全局變量
redirect_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={}&redirect_uri={}&response_type=code&scope={}&state={}&connect_redirect=1#wechat_redirect".format(APP_ID, REDIRECT_URI, SCOPE, STATE)
# print(redirect_url)
return HttpResponseRedirect(redirect_url) #向微信服務器做跳轉
user_info.html模板:
yoooko.cnHello
oauth_state:
{{ oauth_info.oauth_state }}
oauth_code:
{{ oauth_info.oauth_code }}
{{ user_info }}
2017-07-29:結貼
昨天研究了半天,也沒解決,看到出錯的http頭里面有PHPSESSID,回頭去修改了一下程序里的session部分的代碼(這部分代碼在微信網頁授權之后),,也不知道是騰訊那邊修正了bug還是我修改了正確的session代碼,反正這個問題沒了,已經正常運行了一天了~
2017-07-28:第三次更新
加了https之后,就我自己調試的那個賬號的安卓設備可以了,其他賬號還是會出現問題,而且這次不出錯誤40163了,壓根白頁面,過會兒出現網頁找不到,復制鏈接一看還在index.php里,壓根不轉入oauth.php了,看來問題的確是在公眾號后臺那邊。
不用https,用日志記錄,確實oauth.php被調用了兩次,http頭記錄如下:
error
2017-07-27 14:48:29 【021HVeVO1RRzU31O5ZXO1LdhVO1HVeVe】
2017-07-27 14:48:29 【{"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/wxpic,image/sharpp,/;q=0.8","Accept-Encoding":"gzip","Accept-Language":"zh-CN,en-US;q=0.8","Connection":"close","Cookie":"PHPSESSID=2nogkq0l072jvnt8728jonned4","Host":"www.yoookosoft.cn","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Linux; Android 6.0.1; MI 4LTE Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043409 Safari/537.36 MicroMessenger/6.5.10.1080 NetType/WIFI Language/zh_CN","X-Forwarded-For":"114.231.66.45"}】
2017-07-27 14:48:39 【021HVeVO1RRzU31O5ZXO1LdhVO1HVeVe】
2017-07-27 14:48:39 【{"Host":"www.yoookosoft.cn","Connection":"keep-alive","Upgrade-Insecure-Requests":"1","User-Agent":"Mozilla/5.0 (Linux; Android 6.0.1; MI 4LTE Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.49 Mobile MQQBrowser/6.2 TBS/043409 Safari/537.36 MicroMessenger/6.5.10.1080 NetType/WIFI Language/zh_CN","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/wxpic,image/sharpp,/;q=0.8","Accept-Encoding":"gzip, deflate","Accept-Language":"zh-CN,en-US;q=0.8","Cookie":"PHPSESSID=2nogkq0l072jvnt8728jonned4"}】
ok
2017-07-27 14:50:05 【001zXCac2zuXTQ0f747c2CFAac2zXCam】
2017-07-27 14:50:05 【{"Host":"www.yoookosoft.cn","Upgrade-Insecure-Requests":"1","Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8","User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_2 like Mac OS X) AppleWebKit/603.2.4 (KHTML, like Gecko) Mobile/14F89 MicroMessenger/6.5.10 NetType/WIFI Language/zh_CN","Accept-Language":"zh-cn","Accept-Encoding":"gzip, deflate","Connection":"keep-alive"}】
暫時還沒解決辦法,今天繼續排查~
2017-07-26: 第二次更新
并未徹底解決
各種方法解決不了之下,又繼續讀公眾號的官方文檔https://mp.weixin.qq.com/wiki...,讀到這一部分
“授權后重定向的回調鏈接地址,請使用urlEncode對鏈接進行處理”
官方的例子就是用urlEncode的,馬上改成urlEncode,但是錯誤依舊;
“尤其注意:跳轉回調redirect_uri,應當使用https鏈接來確保授權code的安全性。”
再看官方的跳轉地址,第一個snsapi_base是有https的,第二個snsapi_userinfo沒有用https,我的服務器上是有部署https的,馬上在http后面加了個s,我靠,問題解決了!!!安卓也再沒有錯誤40163了,蘋果為什么沒事呢?蘋果的app是強制使用https的,安卓沒有強制!!!為什么每次剛重啟服務器的時候安卓好用的呢?現在的網絡環境太差了,誰知道在傳輸過程中被加了些什么?看來https真的是有必要大力推廣!!!
以下是官方的例子:
scope為snsapi_base
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdap
ter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_bas
e&state=123#wechat_redirect
scope為snsapi_userinfo
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=
code&scope=snsapi_userinfo&state=STATE#wechat_redirect
2017-07-26:第一次更新
我又在header之前加了不使用緩存,強制不使用緩存,還是有這個錯誤~
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Cache-Control: no-cache");
header("Pragma: no-cache");
header('location:https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$myappurl.'oauth.php&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect');
然后找了【微信web開發者工具】,在pc上模擬訪問微信網頁授權,這次發現點線索,照理說用snsapi_userinfo方式訪問微信網頁授權(如果是snsapi_base是不會出現下面的窗口的),會跳一個授權窗口,
如果近期已經授權過,就出這個畫面
我懷疑是不是跟這里有關,在安卓手機上現在不顯示上述提示窗口了,然后進度條走了很長時間之后,就開始出錯誤40163,在【微信web開發者工具】上是會出現提示窗口的!感覺應該是微信安卓版的問題,但是微信又沒有什么可以提問的平臺,微信客服形同虛設,真郁悶。
我想了個不太靠譜的方案,不知道是否可行,,如果我攔截到錯誤40163,就再去訪問一次index.php,再去獲取一次code,再回到oauth.php處理,嘗試3次,如果還是出現,就給個錯誤頁面,,但是估計可能沒用,一旦出現了40163,就會一直出現這個錯誤,周六上午一直出這個錯,但是今天周一,安卓又好的
猜測是公眾號后臺那邊遇到了阻塞?處理安卓和ios請求的是不同的服務器,進了不同的處理隊列,但是后端一般應該是不會區分是來自什么平臺發送的請求,應該是一視同仁處理請求的吧~
總結
以上是生活随笔為你收集整理的android user-agent iso-8859-1,微信网页授权,错误40163,ios正确,安卓错误?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 共享数据,android
- 下一篇: android dispatchtouc