走向匿名化,談談微信小程序新授權登錄
In 未分類 on 2021年04月16日 by view: 15,425
1

今年 2 月,微信團隊針對小程序登錄和用戶信息獲取進行了一次接口調整,這一舉動史無前例地撼動了幾乎所有小程序開發者,在小程序社區產生了不小的反響。

作為接入方,本文將從產品和技術兩個角度,討論微信新授權登錄機制的設計目的、適配方案以及對產品帶來的影響。

歷史淵源:授權、登錄與獲取用戶信息

在微信問世之前,來自 Twitter 的 OAuth 模型就已經足夠普及。在 OAuth 模型中,B 業務想要操作用戶在 A 業務中的數據,需要首先跳轉到 A 業務的頁面,讓用戶直接與 A 業務進行確認,稱為授權(Authorization),得到 A 業務頒發給 B 業務的「兌換碼」(一般稱為 code),并回跳到 B 業務;之后,B 業務使用這個兌換碼,通過后端直接聯系 A 業務,一次性獲得用于操作 A 業務數據的一系列憑證,并進行保存,后續則可以使用這些憑證調用 A 業務中的操作。

在 OAuth 模型中,Auth 這一縮寫代表了兩層含義:「授權(Authorization)」指用戶直接聯系 A 業務,對操作進行確認的過程;而「驗證(Authentication)」則多指 A 業務對 B 業務的訪問權進行校驗的后續流程。

微信公眾號網頁開發實現了這一模型:

對于授權,公眾號網頁需要先跳轉到微信提供的授權頁面,由用戶點擊確認授權(如果無需獲取用戶信息,或用戶已經授權,或已經關注過服務號,則無需確認,但仍然需要進行這一次跳轉),授權頁面會回跳到公眾號網頁業務,并帶上 code 到網頁參數;之后,業務方則需要通過后端攔截前端 Ajax 請求等方式,經由業務自己的后端換取微信頒發的 OpenID/UnionID 以及一個 access_token 憑證;

對于登錄,其本質是區分用戶、頒發登錄態。OpenID/UnionID 代表了用戶在微信的身份信息,讓業務后端能夠區分相同和不同的用戶,業務后端可以針對相同的用戶頒發已有的登錄態信息,訪問同一個用戶之前產生的數據;針對不同的用戶,則可以創建新的帳號信息,下發新的登錄態等;

對于獲取用戶信息,后端可以用 access_token 向微信請求獲得。

小程序老授權登錄

在微信小程序中,由于微信客戶端擁有控制力,第三方業務與微信之間不再需要跳轉,只要調用微信提供的接口,微信客戶端可以保證授權的有效性,因此授權登錄相比網頁開發較為簡單,但這同時也意味著微信隨時可以改變接口的行為。直到目前,小程序授權登錄的行為發生過兩次改動:

小程序剛推出時,微信提供了 wx.loginwx.getUserInfo 兩個接口,分別用于登錄授權獲取用戶信息;其中 wx.login 是靜默的,會直接返回可換取 OpenID 的 code 和用于解密數據的 session_key;wx.getUserInfo 會彈出授權彈窗,經過授權后,會返回加密的用戶數據,可以由后端憑 session_key 進行解密。加密的目的是為了防止用戶篡改信息,從而限制違規頭像昵稱的產生,這一點不在本文的討論范圍內。

此后不久,wx.getUserInfo 被改為不再主動彈出授權,而是會在未授權情況下靜默失??;授權則需要使用微信提供的專門 button 組件進行觸發,這是為了遏止部分小程序一啟動就彈出授權,或在本來不需要用戶信息的情況下超標獲取的問題。對于一些使用 WebView 的小程序,由于 WebView 頁面中無法承載原生的 button 組件,這次改動就需要使用一個原生的授權頁面來適配。

老的這一套授權登錄流程雖然有它繁瑣的地方,但長久以來,我們都忘記了其中最大的一個方便點:經過一次授權之后,小程序可以隨時靜默獲取用戶的信息。當用戶更改了昵稱或頭像,只要打開已授權的小程序,小程序就能直接獲取到修改后的信息,而無需用戶再次授權。

新授權登錄的產品形態

從官方文檔中可以看出,小程序授權登錄機制調整后,主要存在兩個改動點:

  1. wx.login 接口中,現在可以直接獲取到用戶的 UnionID,而無需通過授權獲得,這其實是修復了之前的 Bug,同時鼓勵各小程序業務盡可能不超標獲取用戶信息,遵循權限最小化原則;
  2. 新增了 wx.getUserProfile 接口,代替原來的 wx.getUserInfo,新的接口會主動彈出授權,但只能一次性獲取當前的昵稱頭像,而且仍然需要在用戶點擊后調用。

從產品角度而言,這兩點分別帶來了不同的變化:

第一點對于需要獲取 UnionID 的業務來說,可以讓靜默登錄的能力真正可用??梢宰層脩粼诓皇跈嚓欠Q頭像的情況下,使用盡可能多的功能,在需要時才提示授權,對于產品本身登錄過程的轉化率有很大幫助,同時也幫助微信保護用戶隱私,是一個雙贏的舉措;

而第二點變化則可以看作是微信對用戶信息匿名化的一個嘗試。在此之前,微信推出了自定義昵稱頭像的功能,可以在授權時設置自定義的昵稱頭像,區別于微信本身的昵稱頭像,實現一定的匿名使用;但由于老授權登錄接口是一次授權,用戶一旦設置了自定義的昵稱頭像就無法修改。因此,為了能將一次授權改為每次授權,微信通過新增一個接口,讓開發者對這一行為進行主動適配。

根據微信的要求,4 月 13 日之后,新發布的版本在支持 wx.getUserProfile 的情況下,不能再使用 wx.getUserInfo,否則將收到默認的昵稱頭像。從微信開發者工具中也可以提前看到這一改動:獲取到的頭像會變成一張默認頭像,昵稱變為「微信用戶」。

而適配這個接口也意味著產品交互需要發生改變,因為在此之后,一次授權只能獲得一次性的昵稱和頭像,當用戶對微信昵稱頭像進行了修改,小程序業務不但不能靜默獲取到修改后的昵稱頭像,完全無從得知頭像昵稱發生了變化,都必須通過重新授權才能實現。

對于本來需要獲取用戶昵稱頭像的小程序業務,我們探討了一種比較合理的適配方式:模擬原來的一次授權、并且提供手動修改頭像昵稱的入口。通過對登錄邏輯的改造,可以實現盡可能模擬原有的授權交互,只在首次使用時進行授權,但經過這一次授權后,昵稱頭像不會再更新;因此需要提供手動修改頭像昵稱的入口,讓用戶對「頭像昵稱不會自動同步、可以手動更新或修改」的行為有預期。

技術適配方案:以文檔小程序為例

在文檔小程序中,原有的登錄接口是二合一的,即前端先調用完 wx.loginwx.getUserInfo,得到 code 和加密的用戶信息,然后一起調用后端接口,后端查詢已有用戶或創建新用戶,并對用戶頭像昵稱信息進行更新。

在新授權登錄的背景下,這樣的后端接口已經無法滿足要求。為了盡可能還原原有的一次授權交互,我們需要先判斷用戶是否已授權,然后根據是否已有昵稱頭像,決定是否調用授權并上傳用戶的昵稱頭像。另外,在用戶選擇手動更新昵稱頭像時,也需要有接口負責上傳更新用戶的昵稱頭像。

因此,為了保持接口設計的合理性,我們將登錄接口拆分成兩個接口,并搭配獲取業務用戶信息的接口進行實現:

  1. 前端調用 wx.login,得到 code,并調用后端登錄接口,得到提前頒發的登錄態;
  2. 前端調用現有的獲取業務用戶信息接口,判斷業務是否已獲得昵稱頭像,如果已有昵稱頭像,直接保存 1 中的登錄態,登錄完成;
  3. 如果還未獲得昵稱頭像,則彈出授權,授權后調用后端上傳昵稱頭像接口,將得到的昵稱頭像進行保存;
  4. 根據產品交互設計,在用戶選擇更新昵稱頭像時,重復 3 中的步驟,授權并更新昵稱頭像。

由于 wx.getUserProfile 只返回了明文的昵稱頭像等信息,我們還需要對上傳昵稱頭像的接口接入內容安全保護,防止用戶任意上傳不合規的昵稱頭像信息。

除此之外,在 QQ 小程序以及 PC/Mac 微信小程序的情況下,新的授權登錄接口可能并沒有支持,需要對不支持 wx.getUserProfile 接口的情況進行兼容,改用原有的授權登錄邏輯。

總結

本文探討了微信小程序新的授權登錄機制。新的機制下,授權被局限于獲取用戶信息的一次性操作之內,從而在鼓勵開發者盡可能少要求授權的同時,讓用戶隱私得到一定程度的保護。對于產品形態而言,這要求產品在交互上強化用戶頭像昵稱的可定制性;從開發角度,則需要根據具體業務情況,投入一定的精力進行適配。

與此同時,我們也能看出在小程序授權登錄內外的一些細節問題:接口頻繁變動、適配期限太匆忙,會導致開發者疲于適配,對平臺產生消極情緒;另外,比起頭像昵稱這些常規信息的定制,真正屬于用戶隱私的手機號碼、實名身份等信息仍然需要更嚴格的管控,才能在隱私安全的方向上走得更遠。

小程序是一個為控制力而生的平臺,但我們更希望這樣的控制力去約束不守規矩的開發者,管住一味營銷、缺乏實用性的產品,放手讓用心打磨的項目走得更遠。

原創文章轉載請注明:

轉載自AlloyTeam:http://www.ecomenagepro.com/2021/04/15431/

  1. Bacteria 2021 年 10 月 10 日

    目前很多小程序會要求第一次使用的用戶授權微信賬號、綁定的手機號碼、位置服務等,部分小程序提供的功能根本用不到這些,但還是會申請(說是申請但拒絕就沒法用)

發表評論