- 由于微信官方文檔對(duì)此的描述雖然還可以蚕键,但是還是有一些讓人疑惑的地方又碌,所以筆者做了一些注解咬崔,希望對(duì)大家有所幫助
為什么不直接寫(xiě)一遍呢?因?yàn)閼小?/li>- 為方便大家后續(xù)找資料,文中出現(xiàn)的鏈接匯總放到了文章末尾
- 由于時(shí)間和水平有限尸诽,會(huì)有錯(cuò)漏达皿。如果讀者發(fā)現(xiàn)問(wèn)題叶洞,請(qǐng)及時(shí)聯(lián)系博主敛滋。
微信登錄和綁定微信
官方文檔請(qǐng)看 :網(wǎng)站應(yīng)用微信登錄開(kāi)發(fā)指南
下面是搬運(yùn)(紅色字體為注釋或補(bǔ)充
)。當(dāng)然替废,后面會(huì)有總結(jié)的箍铭,不是全部搬運(yùn),放心椎镣。
準(zhǔn)備工作
網(wǎng)站應(yīng)用微信登錄是基于OAuth2.0協(xié)議標(biāo)準(zhǔn)構(gòu)建的微信OAuth2.0授權(quán)登錄系統(tǒng)诈火。
在進(jìn)行微信OAuth2.在進(jìn)行微信OAuth2.0授權(quán)登錄接入之前,在微信開(kāi)放平臺(tái)注冊(cè)開(kāi)發(fā)者帳號(hào)状答,并擁有一個(gè)已審核通過(guò)的網(wǎng)站應(yīng)用冷守,并獲得相應(yīng)的AppID和AppSecret,申請(qǐng)微信登錄且通過(guò)審核后惊科,可開(kāi)始接入流程拍摇。
授權(quán)流程說(shuō)明
微信OAuth2.0授權(quán)登錄讓微信用戶使用微信身份安全登錄第三方應(yīng)用或網(wǎng)站,在微信用戶授權(quán)登錄已接入微信OAuth2.0的第三方應(yīng)用后馆截,第三方可以獲取到用戶的接口調(diào)用憑證(access_token)充活,通過(guò)access_token可以進(jìn)行微信開(kāi)放平臺(tái)授權(quán)關(guān)系接口調(diào)用,從而可實(shí)現(xiàn)獲取微信用戶基本開(kāi)放信息和幫助用戶實(shí)現(xiàn)基礎(chǔ)開(kāi)放功能等蜡娶。
微信OAuth2.0授權(quán)登錄目前支持authorization_code模式混卵,適用于擁有server端的應(yīng)用授權(quán)。該模式整體流程為:
- 第三方發(fā)起微信授權(quán)登錄請(qǐng)求窖张,微信用戶允許授權(quán)第三方應(yīng)用后幕随,微信會(huì)拉起應(yīng)用或重定向到第三方網(wǎng)站,并且?guī)鲜跈?quán)臨時(shí)票據(jù)code參數(shù)荤堪;
- 通過(guò)code參數(shù)加上AppID和AppSecret等合陵,通過(guò)API換取access_token枢赔;
- 通過(guò)access_token進(jìn)行接口調(diào)用澄阳,獲取用戶基本數(shù)據(jù)資源或幫助用戶實(shí)現(xiàn)基本操作。
第一步:請(qǐng)求CODE
第三方使用網(wǎng)站應(yīng)用授權(quán)登錄前請(qǐng)注意已獲取相應(yīng)網(wǎng)頁(yè)授權(quán)作用域(scope=snsapi_login)踏拜,則可以通過(guò)在PC端打開(kāi)以下鏈接:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“該鏈接無(wú)法訪問(wèn)”碎赢,請(qǐng)檢查參數(shù)是否填寫(xiě)錯(cuò)誤,如redirect_uri的域名與審核時(shí)填寫(xiě)的授權(quán)域名不一致或scope不為snsapi_login速梗。
參數(shù)說(shuō)明
參數(shù) | 是否必須 | 說(shuō)明 |
---|---|---|
appid | 是 | 應(yīng)用唯一標(biāo)識(shí) |
redirect_uri | 是 | 請(qǐng)使用urlEncode對(duì)鏈接進(jìn)行處理肮塞,redirect_uri是微信服務(wù)器在用戶掃碼操作之后襟齿,通過(guò)調(diào)用這個(gè)url把事件發(fā)送給我們的后端,也就是說(shuō)枕赵,這個(gè)redirect_uri猜欺,是一個(gè)api,但這個(gè)api是可以在公網(wǎng)上curl連接的拷窜。我們要在開(kāi)放平臺(tái)添加網(wǎng)站應(yīng)用的時(shí)候設(shè)置一個(gè)回調(diào)域名开皿,這個(gè)回調(diào)域名,就是redirect_uri的前綴篮昧,加上回調(diào)api的名字赋荆,就是完整的redirect_uri。(看不懂不要緊懊昨,后面有舉例)
|
response_type | 是 | 填code |
scope | 是 | 應(yīng)用授權(quán)作用域窄潭,擁有多個(gè)作用域用逗號(hào)(,)分隔,網(wǎng)頁(yè)應(yīng)用目前僅填寫(xiě)snsapi_login即 |
state | 否 | 用于保持請(qǐng)求和回調(diào)的狀態(tài)酵颁,授權(quán)請(qǐng)求后原樣帶回給第三方嫉你。該參數(shù)可用于防止csrf攻擊(跨站請(qǐng)求偽造攻擊),建議第三方帶上該參數(shù)躏惋,可設(shè)置為簡(jiǎn)單的隨機(jī)數(shù)加session進(jìn)行校驗(yàn) |
返回說(shuō)明
用戶允許授權(quán)后均抽,將會(huì)重定向到redirect_uri的網(wǎng)址上,并且?guī)蟘ode和state參數(shù)
redirect_uri?code=CODE&state=STATE
若用戶禁止授權(quán)其掂,則重定向后不會(huì)帶上code參數(shù)油挥,僅會(huì)帶上state參數(shù)
redirect_uri?state=STATE
為了滿足網(wǎng)站更定制化的需求,我們還提供了第二種獲取code的方式款熬,支持網(wǎng)站將微信登錄二維碼內(nèi)嵌到自己頁(yè)面中深寥,用戶使用微信掃碼授權(quán)后通過(guò)JS將code返回給網(wǎng)站。(我們主要講的就是這一種
)
JS微信登錄主要用途:網(wǎng)站希望用戶在網(wǎng)站內(nèi)就能完成登錄贤牛,無(wú)需跳轉(zhuǎn)到微信域下登錄后再返回惋鹅,提升微信登錄的流暢性與成功率。 網(wǎng)站內(nèi)嵌二維碼微信登錄JS實(shí)現(xiàn)辦法:
步驟1:在頁(yè)面中先引入如下JS文件(支持https):
http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
步驟2:在需要使用微信登錄的地方實(shí)例以下JS對(duì)象:
var obj = new WxLogin({ self_redirect:true, id:"login_container", appid: "", scope: "", redirect_uri: "", state: "", style: "", href: "" });
參數(shù)說(shuō)明
參數(shù) | 是否必須 | 說(shuō)明 |
---|---|---|
self_redirect | 否 | true:手機(jī)點(diǎn)擊確認(rèn)登錄后可以在 iframe 內(nèi)跳轉(zhuǎn)到 redirect_uri殉簸,false:手機(jī)點(diǎn)擊確認(rèn)登錄后可以在 top window 跳轉(zhuǎn)到 redirect_uri闰集。默認(rèn)為 false。 |
id | 是 | 第三方頁(yè)面顯示二維碼的容器id |
appid | 是 | 應(yīng)用唯一標(biāo)識(shí)般卑,在微信開(kāi)放平臺(tái)提交應(yīng)用審核通過(guò)后獲得 |
scope | 是 | 應(yīng)用授權(quán)作用域武鲁,擁有多個(gè)作用域用逗號(hào)(,)分隔,網(wǎng)頁(yè)應(yīng)用目前僅填寫(xiě)snsapi_login即可 |
redirect_uri | 是 | 重定向地址蝠检,需要進(jìn)行UrlEncode |
state | 否 | 用于保持請(qǐng)求和回調(diào)的狀態(tài)沐鼠,授權(quán)請(qǐng)求后原樣帶回給第三方。該參數(shù)可用于防止csrf攻擊(跨站請(qǐng)求偽造攻擊),建議第三方帶上該參數(shù)饲梭,可設(shè)置為簡(jiǎn)單的隨機(jī)數(shù)加session進(jìn)行校驗(yàn) |
style | 否 | 提供"black"乘盖、"white"可選,默認(rèn)為黑色文字描述憔涉。詳見(jiàn)文檔底部FAQ |
href | 否 | 自定義樣式鏈接订框,第三方可根據(jù)實(shí)際需求覆蓋默認(rèn)樣式。詳見(jiàn)文檔底部FAQ |
第二步:通過(guò)code獲取access_token
通過(guò)code獲取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數(shù)說(shuō)明
參數(shù) | 是否必須 | 說(shuō)明 |
---|---|---|
appid | 是 | 應(yīng)用唯一標(biāo)識(shí)兜叨,在微信開(kāi)放平臺(tái)提交應(yīng)用審核通過(guò)后獲得 |
secret | 是 | 應(yīng)用密鑰AppSecret布蔗,在微信開(kāi)放平臺(tái)提交應(yīng)用審核通過(guò)后獲得 |
code | 是 | 填寫(xiě)第一步獲取的code參數(shù) |
grant_type | 是 | 填authorization_code |
返回說(shuō)明
正確的返回:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN","openid":"OPENID", "scope":"SCOPE","unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"}
參數(shù)說(shuō)明
參數(shù) | 說(shuō)明 |
---|---|
access_token | 接口調(diào)用憑證 |
expires_in | access_token接口調(diào)用憑證超時(shí)時(shí)間,單位(秒) |
refresh_token | 用戶刷新access_token |
openid | 授權(quán)用戶唯一標(biāo)識(shí) |
scope | 用戶授權(quán)的作用域浪腐,使用逗號(hào)(,)分隔 |
unionid | 當(dāng)且僅當(dāng)該網(wǎng)站應(yīng)用已獲得該用戶的userinfo授權(quán)時(shí)纵揍,才會(huì)出現(xiàn)該字段。 |
錯(cuò)誤返回樣例:
{"errcode":40029,"errmsg":"invalid code"}
注意:
1议街、Appsecret 是應(yīng)用接口使用密鑰泽谨,泄漏后將可能導(dǎo)致應(yīng)用數(shù)據(jù)泄漏、應(yīng)用的用戶數(shù)據(jù)泄漏等高風(fēng)險(xiǎn)后果特漩;存儲(chǔ)在客戶端吧雹,極有可能被惡意竊取(如反編譯獲取Appsecret)涂身;2雄卷、access_token 為用戶授權(quán)第三方應(yīng)用發(fā)起接口調(diào)用的憑證(相當(dāng)于用戶登錄態(tài)),存儲(chǔ)在客戶端蛤售,可能出現(xiàn)惡意獲取access_token 后導(dǎo)致的用戶數(shù)據(jù)泄漏丁鹉、用戶微信相關(guān)接口功能被惡意發(fā)起等行為;3悴能、refresh_token 為用戶授權(quán)第三方應(yīng)用的長(zhǎng)效憑證揣钦,僅用于刷新access_token,但泄漏后相當(dāng)于access_token 泄漏漠酿,風(fēng)險(xiǎn)同上冯凹。建議將secret、用戶數(shù)據(jù)(如access_token)放在App云端服務(wù)器炒嘲,由云端中轉(zhuǎn)接口調(diào)用請(qǐng)求宇姚。
第三步:通過(guò)access_token調(diào)用接口
獲取access_token后,進(jìn)行接口調(diào)用夫凸,有以下前提:
1. access_token有效且未超時(shí)浑劳;2. 微信用戶已授權(quán)給第三方應(yīng)用帳號(hào)相應(yīng)接口作用域(scope)。
對(duì)于接口作用域(scope)寸痢,能調(diào)用的接口有以下:
授權(quán)作用域(scope) | 接口 | 接口說(shuō)明 |
---|---|---|
snsapi_base | /sns/oauth2/access_token | 通過(guò)code換取access_token呀洲、refresh_token和已授權(quán)scope |
snsapi_base | /sns/oauth2/refresh_token | 刷新或續(xù)期access_token使用 |
snsapi_base | /sns/auth | 檢查access_token有效性 |
snsapi_userinfo | /sns/userinfo | 獲取用戶個(gè)人信息() (<font color=red>敲黑板</font>) |
其中snsapi_base屬于基礎(chǔ)接口紊选,若應(yīng)用已擁有其它scope權(quán)限啼止,則默認(rèn)擁有snsapi_base的權(quán)限道逗。使用snsapi_base可以讓移動(dòng)端網(wǎng)頁(yè)授權(quán)繞過(guò)跳轉(zhuǎn)授權(quán)登錄頁(yè)請(qǐng)求用戶授權(quán)的動(dòng)作,直接跳轉(zhuǎn)第三方網(wǎng)頁(yè)帶上授權(quán)臨時(shí)票據(jù)(code)献烦,但會(huì)使得用戶已授權(quán)作用域(scope)僅為snsapi_base滓窍,從而導(dǎo)致無(wú)法獲取到需要用戶授權(quán)才允許獲得的數(shù)據(jù)和基礎(chǔ)功能。
接口調(diào)用方法可查閱微信授權(quán)關(guān)系接口調(diào)用指南
F.A.Q
- 什么是授權(quán)臨時(shí)票據(jù)(code)巩那?
答:第三方通過(guò)code進(jìn)行獲取access_token的時(shí)候需要用到吏夯,code的超時(shí)時(shí)間為10分鐘,一個(gè)code只能成功換取一次access_token即失效即横。code的臨時(shí)性和一次保障了微信授權(quán)登錄的安全性噪生。第三方可通過(guò)使用https和state參數(shù),進(jìn)一步加強(qiáng)自身授權(quán)登錄的安全性东囚。 - 什么是授權(quán)作用域(scope)跺嗽?
答:授權(quán)作用域(scope)代表用戶授權(quán)給第三方的接口權(quán)限,第三方應(yīng)用需要向微信開(kāi)放平臺(tái)申請(qǐng)使用相應(yīng)scope的權(quán)限后页藻,使用文檔所述方式讓用戶進(jìn)行授權(quán)桨嫁,經(jīng)過(guò)用戶授權(quán),獲取到相應(yīng)access_token后方可對(duì)接口進(jìn)行調(diào)用份帐。
總結(jié)
-
用微信給的一個(gè)組件wxlogin生成二維碼(其實(shí)生成二維碼就是這么簡(jiǎn)單)
var obj = new WxLogin({ self_redirect:true, id:"login_container", appid: "", scope: "", redirect_uri: "", state: "", style: "", href: "" });
-
redirect_uri:設(shè)定用戶掃碼操作之后璃吧,微信服務(wù)器調(diào)用的api地址(這個(gè)后端api是處理用戶掃碼后的事件的,因?yàn)槲覀兪遣恢烙脩粲袥](méi)有掃碼的废境,所以要通過(guò)微信的服務(wù)器調(diào)用我們的api畜挨,來(lái)讓我們自定義操作來(lái)處理掃碼事件)。redirect_uri地址由我們的
服務(wù)器域名(不能是公網(wǎng)IPX肌朦促!) + 后端api名
組成(至于為什么,看后面)栓始。我們要在微信開(kāi)放平臺(tái)的網(wǎng)站應(yīng)用中設(shè)置一個(gè)回調(diào)域名务冕,就是我們的服務(wù)器域名,以便微信服務(wù)器能調(diào)用我們的api(但我不懂的是幻赚,萬(wàn)一有其他人調(diào)了我們的api咋辦禀忆,hhhh,這個(gè)我后面去查一下吧)落恼。- 設(shè)置方法:微信開(kāi)放平臺(tái)->管理中心->網(wǎng)站應(yīng)用->在應(yīng)用名右邊點(diǎn)擊查看->開(kāi)發(fā)信息->修改(授權(quán)回調(diào)域)
-
- state:會(huì)放在微信服務(wù)器對(duì)后端api的調(diào)用時(shí)post的參數(shù)里箩退,可以用于場(chǎng)景判斷。就是我們是拿這個(gè)二維碼來(lái)實(shí)現(xiàn)登錄的佳谦,那就設(shè)定state為"auth"戴涝,我們的后端api就可以根據(jù)這個(gè)來(lái)對(duì)用戶進(jìn)行響應(yīng)。(當(dāng)然,其實(shí)上面的官方文檔不是讓我們這么用的啥刻,嘻嘻嘻)
-
然后就是用戶掃描二維碼之后奸鸯,我們的網(wǎng)站如何接收用戶的操作,并進(jìn)行響應(yīng)可帽。
-
是利用我們?cè)谖⑿砰_(kāi)放平臺(tái)設(shè)置的回調(diào)地址娄涩,來(lái)讓微信服務(wù)器把用戶的操作通過(guò)回調(diào)我們?cè)趓edirect_uri指定的api來(lái)傳遞給我們的網(wǎng)站后端。現(xiàn)在再看下面這張圖應(yīng)該就會(huì)有一定的理解了映跟。
獲取access_token時(shí)序圖
-
-
后端接收了微信服務(wù)器發(fā)送的信息之后蓄拣,對(duì)用戶的操作進(jìn)行響應(yīng)
-
調(diào)用下面的連接。通過(guò)上面拿到的code換取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
通過(guò)access_token來(lái)獲取用戶的信息努隙,進(jìn)而檢驗(yàn)用戶是否在數(shù)據(jù)庫(kù)內(nèi)球恤,或這把用戶的unionid加進(jìn)相應(yīng)的數(shù)據(jù)庫(kù)表中。
-
可能出現(xiàn)的問(wèn)題及解決
-
實(shí)現(xiàn)展示二維碼時(shí)
這里如果是在本地測(cè)試運(yùn)行荸镊,應(yīng)該會(huì)出現(xiàn)一個(gè)問(wèn)題碎捺,就是redirect_uri參數(shù)錯(cuò)誤。這個(gè)問(wèn)題出現(xiàn)的原因有
沒(méi)有進(jìn)行UrlEncode
-
地址不是我們?cè)谖⑿砰_(kāi)放平臺(tái)設(shè)置的那個(gè)
第一個(gè)好解決贷洲,encode一下就好收厨。但是第二個(gè)問(wèn)題的話,由于填寫(xiě)的地址是要公網(wǎng)可以訪問(wèn)的优构,而我們?cè)诒镜卣{(diào)試的時(shí)候诵叁,是內(nèi)網(wǎng),公網(wǎng)無(wú)法訪問(wèn)钦椭,這樣的話拧额,微信服務(wù)器就無(wú)法回調(diào)我們的api。那這個(gè)問(wèn)題怎么解決呢彪腔?
當(dāng)當(dāng)當(dāng)侥锦,frp,內(nèi)網(wǎng)穿透利器德挣。
frp
-
簡(jiǎn)介
? frp是快速反向代理恭垦,可幫助您將NAT或防火墻后面的本地服務(wù)器公開(kāi)到Internet。到目前為止格嗅,它支持tcp&udp以及http和https協(xié)議番挺,可以在其中將請(qǐng)求通過(guò)域名轉(zhuǎn)發(fā)到內(nèi)部服務(wù)。(github上的)
-
說(shuō)明
? 說(shuō)的大白話一點(diǎn)屯掖,就是我們本地的運(yùn)行的服務(wù)器玄柏,比如網(wǎng)站,是無(wú)法通過(guò)公網(wǎng)直接訪問(wèn)的(就是你的電腦上運(yùn)行的了一個(gè)網(wǎng)站贴铜,它的地址是xxx.xxx.xxx.xxx:8080粪摘,但是你讓你舍友用他的電腦訪問(wèn)這個(gè)地址瀑晒,是無(wú)法訪問(wèn)的),而你要讓他訪問(wèn)你的網(wǎng)站徘意,就要利用有公網(wǎng)域名的服務(wù)器苔悦。有公網(wǎng)域名的服務(wù)器是可以訪問(wèn)的,再讓服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求到你本地的機(jī)子映砖,這樣就實(shí)現(xiàn)了內(nèi)網(wǎng)穿透间坐。
? 這里大家可能就蒙了灾挨,既然我舍友訪問(wèn)不了邑退,那為什么有公網(wǎng)ip的服務(wù)器就能訪問(wèn)我的本地了呢?這不是耍流氓了嗎劳澄。
? 那我下面把frp的運(yùn)作過(guò)程給大家看一下地技,大家應(yīng)該就明白了
-
frp運(yùn)作流程(以http為例):
-
首先,根據(jù)我們的操作系統(tǒng)和架構(gòu)秒拔,從Release頁(yè)面下載最新frp程序莫矗。
- 一份放到服務(wù)器,一份放本地
-
服務(wù)器運(yùn)行frp_server
- 解壓后進(jìn)入frp程序目錄
- 修改配置文件frps.ini如下
# frps.ini [common] bind_port = 7000 # 服務(wù)器上frp運(yùn)行的端口 vhost_http_port = 8080 # 服務(wù)器上接收http請(qǐng)求(eg. 瀏覽器訪問(wèn))的端口
- 然后啟動(dòng)frps(在命令行敲入以下命令)
./frps -c ./frps.ini
-
-
本地運(yùn)行frp_client
解壓后進(jìn)入frp程序目錄
-
修改配置文件frpc.ini如下
# frpc.ini [common] server_addr = xxxx # 服務(wù)器ip server_port = 7000 # 服務(wù)器上frp運(yùn)行的端口 [web] type = http local_port = 80 # 本地服務(wù)運(yùn)行的端口 custom_domains = www.yourdomain.com
-
然后啟動(dòng)frpc(在命令行敲入以下命令)
./frpc -c ./frpc.ini
本地的frp client通過(guò)server_addr連接服務(wù)器上的frp server 砂缩,注意啦作谚,現(xiàn)在,本地已經(jīng)與服務(wù)器建立聯(lián)系
現(xiàn)在庵芭,使用url訪問(wèn)你的本地Web服務(wù)
http://www.yourdomain.com:8080
妹懒,此時(shí),瀏覽器會(huì)先訪問(wèn)服務(wù)器的8080端口双吆,而服務(wù)器接收到請(qǐng)求之后眨唬,把請(qǐng)求轉(zhuǎn)發(fā)給本地的80端口。(反向代理)本地響應(yīng)請(qǐng)求好乐,把數(shù)據(jù)發(fā)給服務(wù)器匾竿,服務(wù)器再把數(shù)據(jù)發(fā)給用戶(eg. 你的舍友)
好,現(xiàn)在已經(jīng)能讓公網(wǎng)訪問(wèn)我們的本地的機(jī)子了蔚万。下一步岭妖,寫(xiě)回調(diào)函數(shù)。
- 回調(diào)函數(shù)(這是我們的一個(gè)示例)
const wxLogin = async (req, res, next) => {
const code = lo.get(req, 'query.code')
const state = lo.get(req, 'query.state')
const userId = lo.get(req, 'rSession.userId')
try {
const result = await web_codeToAccessToken(code) //用code拿access_token
if (state == 'bind') {
if (result.access_token && result.openid && result.unionid) {
//這里寫(xiě)綁定用戶微信相關(guān)操作反璃,如寫(xiě)入數(shù)據(jù)庫(kù)等
const userInfo = await web_accessTokenToUserInfo(result.access_token, result.openid) //用code拿access_token
} else {
// 由于某些原因綁定失敗区转,進(jìn)行處理
}
}
if (state == 'auth') {
if (result.unionid) {
//這里寫(xiě)用戶微信登錄相關(guān)操作
} else {
// 由于某些原因授權(quán)失敗,進(jìn)行處理
}
}
} catch (error) {
console.error(error);
}
}
// 網(wǎng)頁(yè)登錄版扩,用access_token + openid 拿用戶信息
const web_accessTokenToUserInfo = async function (accessToken, openid) {
const result = await fetch(`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openid}`)
const data = await result.json()
return data
}
// 網(wǎng)頁(yè)登錄废离,用 code 拿用戶的 access_token (包括openid 和 unionid)
const web_codeToAccessToken = async function (code) {
const result = await fetch(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${yourAppid}&secret=${yoursecret}&code=${code}&grant_type=authorization_code`)
const data = await result.json()
return data
}
//這里注意appid和secret是你自己的appid和secret
關(guān)注公眾號(hào)
生成帶參數(shù)的二維碼
下面是搬運(yùn)(紅色字體為注釋或補(bǔ)充
)
為了滿足用戶渠道推廣分析和用戶帳號(hào)綁定等場(chǎng)景的需要,公眾平臺(tái)提供了生成帶參數(shù)二維碼的接口礁芦。使用該接口可以獲得多個(gè)帶不同場(chǎng)景值的二維碼蜻韭,用戶掃描后悼尾,公眾號(hào)可以接收到事件推送。
目前有2種類型的二維碼:
1肖方、臨時(shí)二維碼闺魏,是有過(guò)期時(shí)間的,最長(zhǎng)可以設(shè)置為在二維碼生成后的30天(即2592000秒)后過(guò)期俯画,但能夠生成較多數(shù)量析桥。臨時(shí)二維碼主要用于帳號(hào)綁定等不要求二維碼永久保存的業(yè)務(wù)場(chǎng)景 2、永久二維碼艰垂,是無(wú)過(guò)期時(shí)間的泡仗,但數(shù)量較少(目前為最多10萬(wàn)個(gè))。永久二維碼主要用于適用于帳號(hào)綁定猜憎、用戶來(lái)源統(tǒng)計(jì)等場(chǎng)景娩怎。
用戶掃描帶場(chǎng)景值二維碼時(shí),可能推送以下兩種事件:
如果用戶還未關(guān)注公眾號(hào)胰柑,則用戶可以關(guān)注公眾號(hào)截亦,關(guān)注后微信會(huì)將帶場(chǎng)景值關(guān)注事件推送給開(kāi)發(fā)者。
如果用戶已經(jīng)關(guān)注公眾號(hào)柬讨,在用戶掃描后會(huì)自動(dòng)進(jìn)入會(huì)話崩瓤,微信也會(huì)將帶場(chǎng)景值掃描事件推送給開(kāi)發(fā)者。
獲取帶參數(shù)的二維碼的過(guò)程包括兩步踩官,首先創(chuàng)建二維碼ticket却桶,然后憑借ticket到指定URL換取二維碼。
創(chuàng)建二維碼ticket (這里的access_token是通過(guò)公眾號(hào)appid和appsecret拿到的卖鲤,參見(jiàn)[獲取access_token](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html)這篇文章肾扰。由于比較易懂就不多說(shuō)了。但要注意的是:【通過(guò)公眾號(hào)appid和appsecret拿access_token蛋逾,是要在[微信公眾平臺(tái)](https://mp.weixin.qq.com/)設(shè)置獲取access_token的ip白名單的集晚。如果不在白名單,是無(wú)法獲取的区匣,切記偷拔,切記。設(shè)置方法:微信公眾平臺(tái)->開(kāi)發(fā)->基本配置->ip白名單】
)
每次創(chuàng)建二維碼ticket需要提供一個(gè)開(kāi)發(fā)者自行設(shè)定的參數(shù)(scene_id)亏钩,分別介紹臨時(shí)二維碼和永久二維碼的創(chuàng)建二維碼ticket過(guò)程莲绰。
臨時(shí)二維碼請(qǐng)求說(shuō)明
http請(qǐng)求方式: POST
URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST數(shù)據(jù)格式:json
POST數(shù)據(jù)例子:{"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}
或者也可以使用以下POST數(shù)據(jù)創(chuàng)建字符串形式的二維碼參數(shù):
{"expire_seconds": 604800, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
永久二維碼請(qǐng)求說(shuō)明
http請(qǐng)求方式: POST
URL: https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=TOKEN
POST數(shù)據(jù)格式:json
POST數(shù)據(jù)例子:{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": 123}}}
或者也可以使用以下POST數(shù)據(jù)創(chuàng)建字符串形式的二維碼參數(shù):
{"action_name": "QR_LIMIT_STR_SCENE", "action_info": {"scene": {"scene_str": "test"}}}
參數(shù)說(shuō)明
參數(shù) | 說(shuō)明 |
---|---|
expire_seconds | 該二維碼有效時(shí)間,以秒為單位姑丑。 最大不超過(guò)2592000(即30天)蛤签,此字段如果不填,則默認(rèn)有效期為30秒栅哀。 |
action_name | 二維碼類型震肮,QR_SCENE為臨時(shí)的整型參數(shù)值称龙,QR_STR_SCENE為臨時(shí)的字符串參數(shù)值,QR_LIMIT_SCENE為永久的整型參數(shù)值戳晌,QR_LIMIT_STR_SCENE為永久的字符串參數(shù)值 |
action_info | 二維碼詳細(xì)信息 |
scene_id | 場(chǎng)景值ID鲫尊,臨時(shí)二維碼時(shí)為32位非0整型,永久二維碼時(shí)最大值為100000(目前參數(shù)只支持1--100000) |
scene_str | 場(chǎng)景值ID(字符串形式的ID)沦偎,字符串類型疫向,長(zhǎng)度限制為1到64 |
返回說(shuō)明
正確的Json返回結(jié)果:
{"ticket":"gQH47joAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL2taZ2Z3TVRtNzJXV1Brb3ZhYmJJAAIEZ23sUwMEmm
3sUw==","expire_seconds":60,"url":"http://weixin.qq.com/q/kZgfwMTm72WWPkovabbI"}
參數(shù) | 說(shuō)明 |
---|---|
ticket | 獲取的二維碼ticket,憑借此ticket可以在有效時(shí)間內(nèi)換取二維碼豪嚎。 |
expire_seconds | 該二維碼有效時(shí)間搔驼,以秒為單位。 最大不超過(guò)2592000(即30天)疙渣。 |
url | 二維碼圖片解析后的地址匙奴,開(kāi)發(fā)者可根據(jù)該地址自行生成需要的二維碼圖片 |
通過(guò)ticket換取二維碼
獲取二維碼ticket后堆巧,開(kāi)發(fā)者可用ticket換取二維碼圖片妄荔。請(qǐng)注意,本接口無(wú)須登錄態(tài)即可調(diào)用谍肤。
請(qǐng)求說(shuō)明
HTTP GET請(qǐng)求(請(qǐng)使用https協(xié)議)https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=TICKET
提醒:TICKET記得進(jìn)行UrlEncode
返回說(shuō)明
ticket正確情況下啦租,http 返回碼是200,是一張圖片荒揣,可以直接展示或者下載篷角。
HTTP頭(示例)如下:
Accept-Ranges:bytes
Cache-control:max-age=604800
Connection:keep-alive
Content-Length:28026
Content-Type:image/jpg
Date:Wed, 16 Oct 2013 06:37:10 GMT
Expires:Wed, 23 Oct 2013 14:37:10 +0800
Server:nginx/1.4.1
錯(cuò)誤情況下(如ticket非法)返回HTTP錯(cuò)誤碼404。
總結(jié)
1.用戶掃碼之后關(guān)注公眾號(hào)系任,或者恳蹲,用戶取消關(guān)注(這個(gè)是不用掃碼的),微信服務(wù)器都會(huì)推送信息給我們的網(wǎng)站(其實(shí)就是調(diào)用我們約定好的api)
2.這里我們注意到俩滥,不像微信登錄和綁定那樣嘉蕾,在微信開(kāi)放平臺(tái)設(shè)置接收信息的域名,然后還要設(shè)置redirect_uri霜旧。這里的話错忱,直接在微信公眾平臺(tái)設(shè)置接收信息推送的api地址就好了。
- 設(shè)置方法:微信公眾平臺(tái)->開(kāi)發(fā)->基本配置->服務(wù)器配置
3.然后只要用戶關(guān)注了公眾號(hào)或取消關(guān)注挂据,微信服務(wù)器都會(huì)調(diào)用我們?cè)O(shè)置的api以清,推送信息給我們的網(wǎng)站,然后我們的網(wǎng)站后端處理事件崎逃。