最近剛完成了一項小程序的開發任務。徹徹底底地從零開始,其中遇到了不少坑要填,因此來總結一下,希望能幫助到其他人,避免重復踩坑。
登錄態維護
每個人開發小程序,都希望用戶能持續使用自己開發的小程序,那么維護用戶的登錄態就是首要的任務。
無cookie
首先,第一個需要踩的坑就是無cookie
的登錄態要如何維護。
微信官方提供了一個流程圖,我們可以先看看:

簡而言之:
- 在小程序上通過
wx.login()
獲取code
- 將
code
傳到自己的服務器,然后將小程序的secret
和appid
與微信服務器交換openid
和session_key
- 將
session_key
加上隨機數生成sessionId
,然后openid
和session_key
存在session
里 - 小程序將
sessionId
存起來,每次訪問都帶上這個sessionId
小程序獲取code
在小程序的app.js
文件里,onLaunch
函數調用我們寫好的login
函數:
wx.login({
success: function (loginResult) {
wx.getUserInfo({
withCredentials: true,
success: function (userResult) {
// doLogin 就是將這些數據發送到服務器
doLogin(null, {
code: loginResult.code,
encryptedData: userResult.encryptedData,
iv: userResult.iv
})
}
})
}
})
服務器接受到這些數據,就可以和微信服務器交換數據了,這時我們擁有的數據就是openid
和session_key
。
解密用戶信息
通過小程序傳過來的和encryptedData
和iv
,然后還有剛才獲取的session_key
,我們就能解密用戶的信息,通過對比解密出來的openid
和微信交換來的openid
對比,即可知道用戶信息的正確性。
sessionId生成:
function generateSessionId() {
return crypto.randomBytes(32).toString('hex')
}
按理說,我們生成了sessionId
,然后將對應的用戶信息存在session
里就大功告成了。
但是這樣的話,很容易被偽造的暴力的偽造sessionId
攻擊。因此,需要再進一步,生成另外一個校驗數據稱為sessionkey
簡稱sKey
,這時就使用到剛獲取到的session_key
:
function generateSkey(sessionKey) {
const sha1 = (message) => {
return crypto.createHash('sha1').update(message, 'utf8').digest('hex')
}
return sha1(appid + secret + sessionKey)
}
此時我們的session
的key
就是一個前面隨機生成的sessionId
。value
則為:
{
userinfo,
session_key,
sKey
}
然后每次sessionId
傳遞過來的時候,我們獲取對應的session_key
,然后調用generateSkey
生成sKey
,然后和session
里面的sKey
對比即可。
此時,session
的生成大功告成了!
兩個登錄態的問題
首先,調用微信生成的code的login()
函數是有時效的,大概5分鐘。
我們生成的session
也是有時效的。這樣就有兩個登錄態任一出現失效的情況。因此我們需要處理兩個的失效問題。
小程序登錄態
官方提供了wx.checkSession()
方法給我們驗證登錄態是否失效。因此這個失效的話,我們就重新調用之前寫好的login
函數
session失效
這個失效的問題就比較麻煩。很有可能就是發送某一個請求的時候發現session
失效了。
因此我們可以在app.js
的onShow()
里發送請求到服務器測試session
是否過期。過期的話就重新調用login
函數。