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

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

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

一、網頁授權業務設計

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

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

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

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

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

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

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

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

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

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

  • 在微信公眾號請求用戶網頁授權之前,開發者需要先到公眾平台官網中的「開發 -> 接口權限 -> 網頁服務 -> 網頁帳號 -> 網頁授權獲取用戶基本信息」的配置選項中,修改授權回調域名請注意,這裡填寫的是域名(是一個字符串),而不是URL,因此請勿加 // 等協議頭。
  • 微信公眾平台測試號可以在測試號管理頁面中的【體驗接口權限表】一欄,在「網頁服務->網頁賬號->網頁授權獲取用戶基本信息」的操作選項中,點擊修改按鈕,彈出【OAuth2.0網頁授權】對話框,並在授權回調頁面域名輸入框中填寫域名信息,見下面兩張圖所示。
  • 授權回調域名配置規範為全域名,比如需要網頁授權的域名為:www.qq.com,配置以後此域名下面的頁面//www.qq.com/music.html 、 //www.qq.com/login.html 都可以進行OAuth2.0鑒權。但//pay.qq.com 、 //music.qq.com 、 //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),引導關注者打開如下頁面:

//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

//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

//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參數的賦值:

//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:

//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參數的值不能外泄,故部分值使用星號(*)替換:

//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"
}

 

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

敬請期待下一篇文章內容,將真正步入主題「模板消息」,

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

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

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

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