對(duì)于微信二維碼相關(guān)官方文檔的一些注解(微信登錄和綁定微信私杜、關(guān)注公眾號(hào))

  • 由于微信官方文檔對(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)。該模式整體流程為:

  1. 第三方發(fā)起微信授權(quán)登錄請(qǐng)求窖张,微信用戶允許授權(quán)第三方應(yīng)用后幕随,微信會(huì)拉起應(yīng)用或重定向到第三方網(wǎng)站,并且?guī)鲜跈?quán)臨時(shí)票據(jù)code參數(shù)荤堪;
  2. 通過(guò)code參數(shù)加上AppID和AppSecret等合陵,通過(guò)API換取access_token枢赔;
  3. 通過(guò)access_token進(jìn)行接口調(diào)用澄阳,獲取用戶基本數(shù)據(jù)資源或幫助用戶實(shí)現(xiàn)基本操作。
獲取access_token時(shí)序圖

第一步:請(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

  1. 什么是授權(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)登錄的安全性东囚。
  2. 什么是授權(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é)

  1. 用微信給的一個(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í)上面的官方文檔不是讓我們這么用的啥刻,嘻嘻嘻)
  1. 然后就是用戶掃描二維碼之后奸鸯,我們的網(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í)序圖
  1. 后端接收了微信服務(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)題及解決

  1. 實(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

  1. 簡(jiǎn)介

    ? frp是快速反向代理恭垦,可幫助您將NAT或防火墻后面的本地服務(wù)器公開(kāi)到Internet。到目前為止格嗅,它支持tcp&udp以及http和https協(xié)議番挺,可以在其中將請(qǐng)求通過(guò)域名轉(zhuǎn)發(fā)到內(nèi)部服務(wù)。(github上的)

  2. 說(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)該就明白了

  3. frp運(yùn)作流程(以http為例):

    1. 首先,根據(jù)我們的操作系統(tǒng)和架構(gòu)秒拔,從Release頁(yè)面下載最新frp程序莫矗。

      • 一份放到服務(wù)器,一份放本地
    2. 服務(wù)器運(yùn)行frp_server

      1. 解壓后進(jìn)入frp程序目錄
      2. 修改配置文件frps.ini如下
      # frps.ini 
      [common] 
      bind_port = 7000       # 服務(wù)器上frp運(yùn)行的端口
      vhost_http_port = 8080 # 服務(wù)器上接收http請(qǐng)求(eg. 瀏覽器訪問(wèn))的端口
      
      1. 然后啟動(dòng)frps(在命令行敲入以下命令)
      ./frps -c ./frps.ini
      
  1. 本地運(yùn)行frp_client

    1. 解壓后進(jìn)入frp程序目錄

    2. 修改配置文件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    
       
      
    3. 然后啟動(dòng)frpc(在命令行敲入以下命令)

      ./frpc -c ./frpc.ini
      
  1. 本地的frp client通過(guò)server_addr連接服務(wù)器上的frp server 砂缩,注意啦作谚,現(xiàn)在,本地已經(jīng)與服務(wù)器建立聯(lián)系

  2. 現(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端口。(反向代理)

  3. 本地響應(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ù)。

  1. 回調(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)站后端處理事件崎逃。

鏈接匯總

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末掷倔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子个绍,更是在濱河造成了極大的恐慌勒葱,老刑警劉巖勺像,帶你破解...
    沈念sama閱讀 218,036評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異错森,居然都是意外死亡吟宦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)涩维,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)殃姓,“玉大人,你說(shuō)我怎么就攤上這事瓦阐∥铣蓿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,411評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵睡蟋,是天一觀的道長(zhǎng)踏幻。 經(jīng)常有香客問(wèn)我,道長(zhǎng)戳杀,這世上最難降的妖魔是什么该面? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,622評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮信卡,結(jié)果婚禮上隔缀,老公的妹妹穿的比我還像新娘。我一直安慰自己傍菇,他們只是感情好猾瘸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著丢习,像睡著了一般牵触。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咐低,一...
    開(kāi)封第一講書(shū)人閱讀 51,521評(píng)論 1 304
  • 那天揽思,我揣著相機(jī)與錄音,去河邊找鬼渊鞋。 笑死绰更,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的锡宋。 我是一名探鬼主播儡湾,決...
    沈念sama閱讀 40,288評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼执俩!你這毒婦竟也來(lái)了徐钠?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,200評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤役首,失蹤者是張志新(化名)和其女友劉穎尝丐,沒(méi)想到半個(gè)月后显拜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡爹袁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評(píng)論 3 336
  • 正文 我和宋清朗相戀三年远荠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片失息。...
    茶點(diǎn)故事閱讀 39,953評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡譬淳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盹兢,到底是詐尸還是另有隱情邻梆,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評(píng)論 5 346
  • 正文 年R本政府宣布绎秒,位于F島的核電站浦妄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏见芹。R本人自食惡果不足惜剂娄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望辆童。 院中可真熱鬧宜咒,春花似錦惠赫、人聲如沸把鉴。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,889評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)庭砍。三九已至,卻和暖如春混埠,著一層夾襖步出監(jiān)牢的瞬間怠缸,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,011評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工钳宪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留揭北,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評(píng)論 3 370
  • 正文 我出身青樓吏颖,卻偏偏與公主長(zhǎng)得像搔体,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子半醉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容