寫博客主要是用來總結、鞏固知識點,加深本身對這個知識點的理解。同時但願能幫助到有須要的人。若有不正確的地方。能夠在評論區指出。大家的支持。是我不斷進步的源泉。小程序
這裏引用下官方的一張登陸流程圖,我就按照登陸流程圖來說下個人理解。api
客戶端(小程序)獲取當前微信登陸用戶的登陸憑證(code)安全
可經過wx.login api得到。這裏有地方須要注意bash
1.wx.login不會彈受權彈框服務器
2.wx.login換取的code只能使用一次,若是須要新code只能從新調用wx.login接口微信
wx.login({
success:(res)=>{
let code= res.code
}
})
複製代碼
經過上一步得到的臨時登陸憑證傳給服務器端獲取openid和session_key.服務器端須要經過appid、appsecret、(這裏的數據能夠從小程序管理後臺得到)code(第一步獲取到的code)向微信服務端發送請求獲取seeeion_key和openid。爲了安全。建議將得到的session_key加密後再傳給客戶端。cookie
客戶端得到加密後的登陸態後把登陸態存在本地以便後面進行業務請求。因爲小程序中不存在cookie機制。因此能夠把登陸態存儲在storage中。網絡
以上就是微信官方登陸流程圖的一個大致過程。session
可是在實際應用中可能要複雜點?咱們接下來看。app
這裏看一下微信官方的說明
經過 wx.login 接口得到的用戶登陸態擁有必定的時效性。
用戶越久未使用小程序,用戶登陸態越有可能失效。
反之若是用戶一直在使用小程序,則用戶登陸態一直保持有效。
具體時效邏輯由微信維護,對開發者透明。
開發者只須要調用 wx.checkSession 接口檢測當前用戶登陸態是否有效。
複製代碼
這說明若是用戶一直在使用小程序。登陸態就不會過時。反之就會過時。這裏能夠經過wx.checkSession api 來判斷登陸態是否過時。
接下來上代碼。來看下在應用中的登陸態維護。
目前在小程序中須要拉起微信登陸受權的彈框。須要在wxml文件中調用button組件來調用:以下
<button bindgetuserinfo="getInfo" hover-class="none" open-type="getUserInfo"></button>
複製代碼
這樣用戶點擊按鈕的時候會彈出受權獲取用戶信息的彈窗。用戶點擊容許咱們就能夠拿到數據進行登陸並進行業務請求。 若是點擊拒絕能夠獲取不須要登陸可查看的數據請求,並安利用戶拒絕後的結果。從新引導用戶進行受權。
下面是用戶非首次進入應用的一個登陸態維護(首次進入經過button來受權。因此success回調是不會執行的。直接fail的回調。)
// 小程序啓動判斷用戶是否受權,根據是否受權來請求不一樣的業務數據
wx.getSetting({
success: (res) => {
//用戶已受權
if (res.authSetting['scope.userInfo']) {
// 判斷登陸態是否過時
wx.checkSession({
// 登陸態未過時,直接進行業務請求
success: (res) => {
//業務請求代碼。。。
},
// 登陸態已過時 。從新調用wx.login進行登陸換取code
fail: (res) => {
// 能夠在這裏進行從新登陸後的回調
wx.login({
success: function(res) {
let code = res.code;
}
})
}
})
}
// 爲受權
else {
// 執行未受權的業務代碼
}
}
})
複製代碼
附上登陸態過時的回調。
/**
* 登陸失敗後從新登陸
*/
getToken: function(fn) {
let that = this;
let getLogin = new Promise((resolve, reject) => {
//登陸獲取code
wx.login({
success: function(res) {
var code = res.code;
that.globalData.code = code;
resolve([fn, code]);
},
fail: function(res) {
reject();
}
})
});
getLogin.then(([fn, code]) => {
return new Promise((resolve, reject) => {
//使用該api須要在頁面經過button組件觸發受權彈窗
wx.getUserInfo({
success: function(res) {
//這裏的iv,encryptedData等數據是用來服務器端進行解密的。
let requestData = {
"Data": {
"IV": res.iv,
"EncryptedData": res.encryptedData,
"JsCode": code,
},
}
//發送請求
wx.request({
url: that.apiList.login.getLogin,
data: requestData,
method: "POST",
success: function(res) {
//獲取到自定義登陸態存入storage
if (res.data && res.data.Success) {
that.globalData.token = res.data.Data.Key;
wx.setStorageSync('LoginSessionKey', res.data.Data.Key);
resolve(fn);
} else {
reject();
}
},
fail: function() {
Hq.tipMaskNoneIcon('您的網絡開小差了');
}
})
}
})
});
}).then((fn) => {
that.getCountryInfo(fn);
}, function() {}))
},
//執行fn回調函數
getCountryInfo: function(fn) {
if (typeof fn == 'function') {
//登陸成功後進行業務請求。
fn();
} else {
Hq.afterSend();
}
},
複製代碼
以上就是個人一些理解。有語句不通,邏輯不清晰的地方,請不吝留言賜教!
感謝閱讀個人文章!