需要將 <button> 組件 open-type 的值設置為 getPhoneNumber。用戶點擊後會彈出壹個授權彈窗讓用戶確認(若該用戶賬戶未綁定手機號碼會執行壹次綁定手機號碼的流程;授權彈窗每次使用都會彈出)。 用戶同意後,開發者可以通過 bindgetphonenumber 事件回調獲取到壹個加密數據,開發者可以把該數據傳回到自己的服務端進行解密獲取手機號。
獲取到的加密數據需要使用sessionKey進行解密,因此在獲取用戶信息前,需要登錄壹次,獲取到code,然後根據code獲取到sessionKey,再根據sessionKey進行加密數據的解密,解析出手機號。
根據博主猜測,抖音在登錄後會生成壹個code,和壹個對應的sessionKey,在會話期間(session未過期)的時候獲取用戶信息,會將用戶信息使用sessionKey進行數據的加密,進行數據的解密也需要使用到sessionKey。code和sessionKey是對應的,但是它們的失效期是不壹樣的,code的失效期是3分鐘,sessionKey的失效時間是不定的,只要用戶活躍在頁面上都不會失效。在獲取到code的3分鐘內調用 code-2-session 接口,會獲取到sessionKey,如果3分鐘後根據code獲取sessionKey將會獲取失敗,因此解密也會失敗。
因為無法判斷用戶什麽時候開始獲取用戶信息,所以用戶壹進入頁面,前端就會調用 tt.login 接口進行登錄,然後放到localstorage緩存中,在用戶點擊按鈕時,彈出授權框用戶確認後獲取到用戶信息的加密數據,然後前端將緩存的code和加密數據壹並傳給後端。後端用code先去調用 code-2-session 接口獲取到sessionKey,然後以sessionKey為密鑰進行AES解密,獲取到手機號返回給前臺。整個流程看起來沒什麽問題,但是壹旦用戶在頁面停留時間超過3分鐘,然後再去獲取用戶信息會失敗,主要是因為code已經失效,獲取sessionKey會失敗。
目前的問題就是過了code的有效期後,根據code獲取sessionKey失敗。那麽在前端login獲取到code後,先緩存到本地,然後立即調用後臺接口去獲取sessionKey然後緩存到redis裏面,key為code,value為sessionKey。失效時間根據自己的業務設置(小程序頁面用戶不會停留太久,因此緩存失效時間設置為30分鐘),用戶退出小程序後,會重新login,然後也會存壹份新的code和sessionKey的對應值。
用戶在授權到用戶信息後,前端直接將緩存的code和加密後的用戶信息上傳到服務到進行解密。服務端根據code從緩存中先獲取到sessionKey,然後再用sessionKey進行解密,解析出手機號進行返回。
以上解決辦法每次基本都可以獲取手機號成功,但是也會存在壹些問題
UserInfoController主要提供兩個接口,壹個是解密手機號和code2seesion操作
TiktokEncryptedParam 主要是前端傳過來的code和加密後的數據
TiktokUserInfoSPI 主要是對接口的封裝
TiktokUserInfoSPIAdapter 實現接口
使用AES對稱加密