我們發現大部分小程序都會使用 wx.getUserInfo 接口,來獲取用戶信息。原本設計這個接口時,我們希望開發者在真正需要用戶信息的情況下才去調取這個接口,但很多開發者會直接調用這個接口,導致用戶在使用小程序的時候產生困擾,歸結起來有幾點:
此外,我們發現開發者默認將 wx.login 和 wx.getUserInfo 綁定使用,這個是由于我們一開始的設計缺陷和實例代碼導致的(wx.getUserInfo 必須通過 wx.login 在后臺生成 session_key后才能調用)。同時,我們收到開發者的反饋,希望用戶進入小程序首頁便能獲取到用戶的 unionId,以便識別到用戶是否以前關注了同主體公眾號或使用過同主體的App 。
為了解決以上問題,針對獲取用戶信息我們更新了三個能力:
1.使用組件來獲取用戶信息
2.若用戶滿足一定條件,則可以用wx.login 獲取到的code直接換到unionId
3.wx.getUserInfo 不需要依賴 wx.login 就能調用得到數據
獲取用戶信息組件介紹
<button/> 組件變化:
示例:
<button open-type="getUserInfo" bindgetuserinfo="userInfoHandler"> Click me </button>
和 wx.getUserInfo 不同之處在于:
1.API wx.getUserInfo 只會彈一次框,用戶拒絕授權之后,再次調用將不會彈框;
2.組件 <button open-type="getUserInfo"> 由于是用戶主動觸發,不受彈框次數限制,只要用戶沒有授權,都會再次彈框。
通過獲取用戶信息的組件,就可以解決用戶再次授權的問題。
開發者申請 userinfo 授權主要為了獲取 unionid,我們鼓勵開發者在不騷擾用戶的情況下合理獲得unionid,而僅在必要時才向用戶彈窗申請使用昵稱頭像。為此,凡使用“獲取用戶信息組件”獲取用戶昵稱頭像的小程序,在滿足以下全部條件時,將可以靜默獲得 unionid:
1.在微信開放平臺下存在同主體的App、公眾號、小程序。
2.用戶關注了某個相同主體公眾號,或曾經在某個相同主體App、公眾號上進行過微信登錄授權。
這樣可讓其他同主體的App、公眾號、小程序的開發者快速獲得已有用戶的數據。
某些工具類的輕量小程序不需要登錄行為,但是也想獲取用戶信息,那么就可以在 wx.getUserInfo 的時候加一個參數 withCredentials: false 直接獲取到用戶信息,可以少一次網絡請求。
這樣可以在不給用戶彈窗授權的情況下直接展示用戶的信息。
最佳實踐
1.調用 wx.login 獲取 code,然后從微信后端換取到 session_key,用于解密 getUserInfo返回的敏感數據。
2.使用 wx.getSetting 獲取用戶的授權情況
1) 如果用戶已經授權,直接調用 API wx.getUserInfo 獲取用戶最新的信息;
2) 用戶未授權,在界面中顯示一個按鈕提示用戶登入,當用戶點擊并授權后就獲取到用戶的最新信息。
3.獲取到用戶數據后可以進行展示或者發送給自己的后端。
One More Thing
除了獲取用戶方案介紹之外,再聊一聊很多初次接觸微信小程序的開發者所不容易理解的一些概念:
1.關于OpenId和UnionId
OpenId 是一個用戶對于一個小程序/公眾號的標識,開發者可以通過這個標識識別出用戶。
UnionId 是一個用戶對于同主體微信小程序/公眾號/APP的標識,開發者需要在微信開放平臺下綁定相同賬號的主體。開發者可通過UnionId,實現多個小程序、公眾號、甚至APP 之間的數據互通了。
同一個用戶的這兩個 ID 對于同一個小程序來說是永久不變的,就算用戶刪了小程序,下次用戶進入小程序,開發者依舊可以通過后臺的記錄標識出來。
2.關于 getUserInfo 和 login
很多開發者會把 login 和 getUserInfo 捆綁調用當成登錄使用,其實 login 已經可以完成登錄,getUserInfo 只是獲取額外的用戶信息。
在 login 獲取到 code 后,會發送到開發者后端,開發者后端通過接口去微信后端換取到 openid 和sessionKey(現在會將 unionid 也一并返回)后,把自定義登錄態 3rd_session返回給前端,就已經完成登錄行為了。而 login 行為是靜默,不必授權的,用戶不會察覺。
getUserInfo 只是為了提供更優質的服務而存在,比如展示頭像昵稱,判斷性別,開發者可通過 unionId 和其他公眾號上已有的用戶畫像結合來提供歷史數據。因此開發者不必在用戶剛剛進入小程序的時候就強制要求授權。
可以在官方的文檔中看到 login 的最佳實踐:
Q & A
Q1: 為什么 login 的時候不直接返回 openid,而是要用這么復雜的方式來經過后臺好幾層處理之后才能拿到?
A: 為了防止壞人在網絡鏈路上做手腳,所以小程序端請求開發者服務器的的請求都需要二次驗證才是可信的。因為我們采取了小程序端只給 code ,由服務器端拿著 code 和 AppSecrect 去微信服務器請求的方式,才會給到開發者對應的openId 和用于加解密的 session_key。
Q2: 既然用戶的openId 是永遠不變的,那么開發者可以使用openId 作為用戶的登錄態么?
A: 不行,這是非常危險的行為。因為 openId 是不變的,如果有壞人拿著別人的 openId 來進行請求,那么就會出現冒充的情況。所以我們建議開發者可以自己在后臺生成一個擁有有效期的 第三方session 來做登錄態,用戶每隔一段時間都需要進行更新以保障數據的安全性。
Q3: 是不是用戶每次打開小程序都需要重新login?
A: 不必,可以將登錄態存入storage中,用戶再次登錄就可以拿storage 里的登錄態做正常的業務請求,只有當登錄態過期了之后才需要重新login 。這樣子做一則可以減少用戶等待時間,二則可以減少網絡帶寬。
目前微信的session_key 有效期是三天,所以建議開發者設置的登錄態有效期要小于這個值。