【C#版本】微信公眾號模板訊息對接(二)(圖文詳解)

張歐昊辰發表於2022-03-06

本篇文章承接上一篇文章內容,點選此段文字傳送至上一篇文章。

特此說明:本篇文章為個人原創文章,創作不易,未經作者本人同意、許可等條件,不得以任何形式搬運、轉載、抄襲(等包括但不限於上述手段)本文章,否則保留追究有關侵權人責任的權利。

一、網頁授權業務設計

可能會有小夥伴要說了,我們不是講解微信模板訊息的開發嘛?怎麼又扯到網頁授權開發了?你這不是跑題了嗎?然而事實並非如此,且聽我慢慢細細道來。

第1步:我們(“訊息推送者”)要給某位公眾號關注者(“訊息接收者”、“訊息被推送者”)推送一條訊息時,我們必須要先知道這位公眾號關注者的唯一且正確的資訊(OpenID或者UnionID)後才能推送訊息(例如:就像你給某人打電話時必須先知道他的正確的電話號碼,不然你怎麼確定你輸入的號碼就是你想打給電話的那個人,是一樣的道理),防止訊息推送給錯誤的公眾號關注者。即該訊息的訊息接收者正是我們要推送的訊息的訊息被推送者

第2步:假設我們已經獲取到公眾號關注者的唯一且正確的資訊,然而獲取到的上述資訊不包含公眾號關注者的特徵資訊,實際上就是一串無任何含義的字串,無法知道這條唯一且正確的資訊對應我們業務系統中的哪位使用者,也有可能這位公眾號關注者還未在我們業務系統中註冊過賬號。

第3步:我們需要在微信公眾號中設計一個資訊雙向繫結的業務需求。在這個頁面中,我們不僅要獲取到公眾號關注者的唯一且正確的資訊,還需要公眾號關注者主動提供並填寫在我們業務系統中使用者主動填寫的自身的具有唯一區分性的資訊(例如:手機號、郵箱號等資訊)。這樣一來,通過中間橋樑資訊(手機號、郵箱號等資訊)就能把公眾號關注者的唯一且正確的資訊與我們業務系統中使用者表裡的唯一資訊(假設是uid)進行繫結。即:我們就能把使用者在我們公眾號的唯一且正確的資訊與我們業務系統中使用者表裡的唯一資訊進行一一對應,形成資訊雙向繫結關係。如果公眾號關注者主動提供的資訊在我們業務系統的使用者表裡不存在,還需要設計使用者註冊等業務需求,註冊成功後再進行資訊雙向繫結。

第4步:當我們業務系統中的某個功能觸發時,需要給公眾號關注者推送提醒訊息,我們便可通過第3步中建立的一一對應雙向繫結關係,拿我們業務系統中使用者的唯一資訊(假設是uid)查詢到公眾號關注者的唯一且正確的資訊。當獲取到公眾號關注者的唯一且正確的資訊後,便可以給其推送微信公眾號訊息啦。

第5步:我們業務系統的使用者唯一資訊獲取非常容易,可公眾號關注者的唯一且正確的資訊怎麼獲取呢?這就是我們下一部分要講解的內容——“網頁授權獲取OpenID”。

下圖大致總結了上述步驟內容,供小夥伴參考:

二、網頁授權獲取OpenID的前提準備及說明

如果使用者在微信客戶端中訪問第三方網頁,公眾號可以通過微信網頁授權機制,來獲取使用者基本資訊,進而實現業務邏輯。

1、關於網頁授權回撥域名的說明

  • 在微信公眾號請求使用者網頁授權之前,開發者需要先到公眾平臺官網中的“開發 -> 介面許可權 -> 網頁服務 -> 網頁帳號 -> 網頁授權獲取使用者基本資訊”的配置選項中,修改授權回撥域名請注意,這裡填寫的是域名(是一個字串),而不是URL,因此請勿加 http:// 等協議頭。
  • 微信公眾平臺測試號可以在測試號管理頁面中的【體驗介面許可權表】一欄,在“網頁服務->網頁賬號->網頁授權獲取使用者基本資訊”的操作選項中,點選修改按鈕,彈出【OAuth2.0網頁授權】對話方塊,並在授權回撥頁面域名輸入框中填寫域名資訊,見下面兩張圖所示。
  • 授權回撥域名配置規範為全域名,比如需要網頁授權的域名為:www.qq.com,配置以後此域名下面的頁面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以進行OAuth2.0鑑權。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com 無法進行OAuth2.0鑑權。
  • 如果公眾號登入授權給了第三方開發者來進行管理,則不必做任何設定,由第三方代替公眾號實現網頁授權即可。

2、關於網頁授權的兩種scope的區別說明

  • 以snsapi_base為scope發起的網頁授權,是用來獲取進入頁面的使用者的openid的,並且是靜默授權並自動跳轉到回撥頁的。使用者感知的就是直接進入了回撥頁(往往是業務頁面)
  • 以snsapi_userinfo為scope發起的網頁授權,是用來獲取使用者的基本資訊的。但這種授權需要使用者手動同意,並且由於使用者同意過,所以無須關注,就可在授權後獲取該使用者的基本資訊。
  • 使用者管理類介面中的“獲取使用者基本資訊介面”,是在使用者和公眾號產生訊息互動或關注後事件推送後,才能根據使用者OpenID來獲取使用者基本資訊。這個介面,包括其他微信介面,都是需要該使用者(即openid)關注了公眾號後,才能呼叫成功的。

3、關於網頁授權access_token和普通access_token的區別

  • 微信網頁授權是通過OAuth2.0機制實現的,在使用者授權給公眾號後,公眾號可以獲取到一個網頁授權特有的介面呼叫憑證(網頁授權access_token),通過網頁授權access_token可以進行授權後介面呼叫,如獲取使用者基本資訊;
  • 其他微信介面,需要通過基礎支援中的“獲取access_token”介面來獲取到的普通access_token呼叫。

4、UnionID機制,以及UnionID與OpenID的區別和聯絡

微信公眾號開發文件中已有多處關於該方面資訊的詳細介紹,本人在此就不再贅述,有興趣的小夥伴可以自行上網查閱相關資料進行了解。

5、網頁授權流程

具體而言,網頁授權流程分為以下四步,我們目前暫時只用到前面兩步即可滿足業務需求:

  1. 引導使用者進入授權頁面->使用者同意授權->獲取code
  2. 通過code換取網頁授權access_token(與基礎支援中的access_token不同)
  3. 如果需要,開發者可以重新整理網頁授權access_token,避免過期
  4. 通過網頁授權access_token和openid獲取使用者基本資訊(支援UnionID機制)

三、網頁授權獲取OpenID

第1步:使用者同意授權,獲取code

在確保微信公眾賬號擁有授權作用域(scope引數)的許可權的前提下(服務號獲得高階介面後,預設擁有scope引數中的snsapi_base和snsapi_userinfo),引導關注者開啟如下頁面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

若提示“該連結無法訪問”,請檢查引數是否填寫錯誤,是否擁有scope引數對應的授權作用域許可權。

尤其注意:由於授權操作安全等級較高,所以在發起授權請求時,微信會對授權連結做正則強匹配校驗,如果連結的引數順序不對,授權頁面將無法正常訪問

此處提供微信官方給予的參考連結(請在微信客戶端中開啟此連結體驗):

  • 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%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&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

尤其注意:跳轉回撥redirect_uri,應當使用https連結來確保授權code的安全性。

下面講解引數說明:

引數 是否必須 說明
appid 公眾號的唯一標識
redirect_uri 授權後重定向的回撥連結地址, 請使用 urlEncode 對連結進行處理
response_type 返回型別,請填寫code
scope 應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取使用者openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到暱稱、性別、所在地。並且, 即使在未關注的情況下,只要使用者授權,也能獲取其資訊 )
state 重定向後會帶上state引數,開發者可以填寫a-zA-Z0-9的引數值,最多128位元組
#wechat_redirect 無論直接開啟還是做頁面302重定向時候,必須帶此引數

以下為本人測試時所使用的url連結,僅供參考使用,特別注意redirect_uri和state引數的賦值:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx70d54bbda1ef76b8&redirect_uri=http%3A%2F%2Fhuaweiit.kmdns.net%3A8031%2Fweb%2Findex.html&response_type=code&scope=snsapi_base&state=iZOHC#wechat_redirect

以下為本人測試時跳轉後的HTML頁面程式碼,僅供參考使用:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>

    <h1 style="height:200px;width:480px;margin:0 auto; background-color:chocolate">微信公眾號關注使用者網頁授權後,跳轉的頁面</h1>
    <br />
    <div id="weburl" style="height:200px;width:480px;margin:0 auto; background-color:khaki"></div>
    
    <script>
        var url = window.location.href;//獲取當前頁面被開啟時的完整url字串
        document.getElementById("weburl").innerText = url;//把該url字串展示在頁面id為weburl的div中
    </script>

</body>
</html>

測試號的公眾號如何找到並關注呢?在第一篇文章中已有詳細介紹,此處將一筆帶過(在測試號管理頁面中找到“測試號二維碼”一欄,在此欄下方有一張二維碼,此二維碼便是測試號的公眾號二維碼,用微信APP掃一掃功能掃描此碼即可進入測試號的公眾號)。

把上述測試url連結傳送到測試號的公眾號會話框中,如下圖所示:

點選會話框中的連結開啟它,如果使用者同意授權,頁面將跳轉至:

redirect_uri/?code=CODE&state=STATE

跳轉後的頁面顯示如下圖,小夥伴們需要特別關注下圖片中紅色框框出來的內容,正好符合redirect_uri/?code=CODE&state=STATE格式。redirect_uri後面附帶的state引數的值“iZOHC”正是連結中我們賦予的值,被原封不動的返回了;code引數的值正是第二步通過code換取網頁授權access_token中所需要的code值,此時我們已經獲取到了。

code說明:code作為換取access_token的票據,每次使用者授權帶上的code將不一樣,code只能使用一次,5分鐘未被使用自動過期。

使用者同意授權後,跳轉頁面時可能會發生的錯誤返回碼說明如下:

返回碼 說明
10003 redirect_uri域名與後臺配置不一致
10004 此公眾號被封禁
10005 此公眾號並沒有這些scope的許可權
10006 必須關注此測試號
10009 操作太頻繁了,請稍後重試
10010 scope不能為空
10011 redirect_uri不能為空
10012 appid不能為空
10013 state不能為空
10015 公眾號未授權第三方平臺,請檢查授權狀態
10016 不支援微信開放平臺的Appid,請使用公眾號Appid

第2步:通過code換取網頁授權access_token

首先請注意,這裡通過code換取的是一個特殊的網頁授權access_token與基礎支援中的access_token(該access_token用於呼叫其他介面)不同。公眾號可通過下述介面來獲取網頁授權access_token。如果網頁授權的作用域為snsapi_base,則本步驟中獲取到網頁授權access_token的同時,也獲取到了openid,snsapi_base式的網頁授權流程即到此為止。

尤其注意:由於公眾號的secret和獲取到的access_token安全級別都非常高,必須只儲存在伺服器,不允許傳給客戶端。後續重新整理access_token、通過access_token獲取使用者資訊等步驟,也必須從伺服器發起。

在第一步中我們已經獲取到code的值了,接下來請求以下連結獲取access_token:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

引數說明:

引數 是否必須 說明
appid 公眾號的唯一標識
secret 公眾號的appsecret
code 填寫第一步獲取的code引數
grant_type 填寫為authorization_code

以下為本人測試過成中所使用的url連結,因為secret引數的值不能外洩,故部分值使用星號(*)替換:

https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx70d54bbda1ef76b8&secret=2******d&code=061gBaml2rcFK84KWQll2QA2ha0gBamU&grant_type=authorization_code

介面響應正確時返回的JSON資料包如下:

{
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE" 
}

返回引數說明:

引數 描述
access_token 網頁授權介面呼叫憑證,注意:此access_token與基礎支援的access_token不同
expires_in access_token介面呼叫憑證超時時間,單位(秒)
refresh_token 使用者重新整理access_token
openid 使用者唯一標識,請注意,在未關注公眾號時,使用者訪問公眾號的網頁,也會產生一個使用者和公眾號唯一的OpenID
scope 使用者授權的作用域,使用逗號(,)分隔

以下為本人測試時微信伺服器某次響應的正確資料:

{
    "access_token": "54_wCp2aHueMlMUTuoPHr9fg0SY8P0O3m3czggVXvWoBcHCij7i744JigKOyN72LInpsBcp5YpdXELMk2A1ejyi29s4CsGplmjKhiiNvZXqmes",
    "expires_in": 7200,
    "refresh_token": "54_EOTFhoLvuPLb-YnkbLeTSAm_uQqR8ARkfPS58yBtvrSoxjuDGvubOOC3Ri_S41AvmdxssHFMri-GjRq8pu-DcseZU__e5yrD2Y-RLKZAlgg",
    "openid": "oLrmn5rh9480z38etS-YMCDD-cwc",
    "scope": "snsapi_base"
}

以下為本人測試時微信伺服器某次響應的錯誤資料:(示例為Code無效錯誤):

{
    "errcode":40029,
    "errmsg":"invalid code, rid: 62246a80-00401253-0f5aa6b3"
}

 

本篇文章到此結束,但本系列文章還未結束。

敬請期待下一篇文章內容,將真正步入主題“模板訊息”,

先前文章都是為下一篇文章做鋪墊。

點選此段文字傳送至本系列文章上一篇文章。

喜歡本人文章的小夥伴記得點個關注喲!!!

順帶頂一下本文,讓更多的小夥伴看到本文並受益!!!

 

相關文章