微信小程式開發使用者授權登入
阿新 • • 發佈:2018-11-06
用wx.login獲取登入憑證code
<!--pages/user/index.wxml--> <view hidden='{{boolean}}'> <view wx:if="{{isLogin == 1}}"> <!-- 個人資訊 --> <view class='infomation'> <!-- 基本資訊 --> <view class="gameTitle"> <navigator hover-class="none" href=""><image src="{{dataList.head_photo}}"></image></navigator> <view> <view class="gameName"><navigator hover-class="none" href="">{{dataList.username}}</navigator></view> <view class="gameSummary" wx:if="{{dataList.title == ''}}"><navigator hover-class="none" href="">這個玩家很懶,什麼也沒留下</navigator></view> <view class="gameSummary" wx:if="{{dataList.title != ''}}"><navigator hover-class="none" href="">{{dataList.title}}</navigator></view> </view> </view> </view> <!-- “我的”列表 --> <view class='myList'> <view class='list'> </view> </view> </view> <view wx:if="{{isLogin == 2}}"> <view class='bgBox'> </view> <view class="unLogin"> </view> </view> </view>
wx.checkSession
小程式 wx.checkSession 校驗登陸態
success :介面呼叫成功,session_key未過期;
fail :介面呼叫失敗,session_key已過期;
- 小程式端 wx.login 獲取code 並 wx.request 提交 code 給己方伺服器
- 伺服器 提交Appid + appSecret + code 到微信方伺服器 獲取 session_key & openid
- 伺服器 根據 session_key & openid 生成 3rd_session(微信方提出的基於安全性的考慮,建議開發者不要將openid等關鍵性資訊進行資料傳輸) 並返回 3rd_session 到小程式端
- 小程式端 wx.setStorage 儲存 3rd_session 在後續使用者操作需要憑證時 附帶該引數
- 小程式端 wx.getUserInfo 獲取使用者資訊 + wx.getStorage 獲取 3rd_session 資料後,一併 wx.request 提交給己方伺服器
- 伺服器 SQL 使用者資料資訊更新
//使用者登陸 function userLogin() { wx.checkSession({ success: function () { //存在登陸態 }, fail: function () { //不存在登陸態 onLogin() } }) } function onLogin() { wx.login({ success: function (res) { if (res.code) { //發起網路請求 wx.request({ url: 'Our Server ApiUrl', data: { code: res.code }, success: function (res) { const self = this if (邏輯成功) { //獲取到使用者憑證 儲存 3rd_session var json = JSON.parse(res.data.Data) wx.setStorage({ key: "third_Session", data: json.third_Session }) getUserInfo() } else { } }, fail: function (res) { } }) } }, fail: function (res) { } }) } function getUserInfo() { wx.getUserInfo({ success: function (res) { var userInfo = res.userInfo userInfoSetInSQL(userInfo) }, fail: function () { userAccess() } }) } function userInfoSetInSQL(userInfo) { wx.getStorage({ key: 'third_Session', success: function (res) { wx.request({ url: 'Our Server ApiUrl', data: { third_Session: res.data, nickName: userInfo.nickName, avatarUrl: userInfo.avatarUrl, gender: userInfo.gender, province: userInfo.province, city: userInfo.city, country: userInfo.country }, success: function (res) { if (邏輯成功) { //SQL更新使用者資料成功 } else { //SQL更新使用者資料失敗 } } }) } }) }
第三方伺服器和微信伺服器:
注意:session_key是微信伺服器生成的針對使用者資料進行加密簽名的金鑰,不應該進行傳輸到客戶端.
生成3rd_session
用於第三方伺服器和小程式之間做登入態校驗.為了保證安全性,3rd_session應該長度夠長,一定有效時間, session_key + openid, key, 為 value, 寫入到session儲存.
3rd_session寫入storage:
後續使用者進入小程式,先從storage讀取3rd_session
根據請求,在session儲存中查詢合法的session_key和openid
App({
onLaunch: function() {
wx.login({
success: function(res) {
var code = res.code;
if (code) {
console.log('獲取使用者登入憑證:' + code);
} else {
console.log('獲取使用者登入態失敗:' + res.errMsg);
}
}
});
}
})
唯一標識(openid)和會話金鑰(session_key)
wx.checkSession
檢測當前使用者登入態是否有效
wx.checkSession({
success: function(){
//session 未過期,並且在本生命週期一直有效
},
fail: function(){
//登入態過期
wx.login() //重新登入
....
}
})
服務端處理邏輯
wx.checkSession({
success:function(res){
//session_key未過期
},
fail:(res=>{
// session_key已過期
// 進行登入操作
wx.login({
success: function(res) {
const url = '介面地址' //本次專案中是從後臺獲取session_key的介面,可能流程不同,會有相應的變化
const data = {
//你要傳的資料
}
wepy.request({
url: url,
method: 'POST',
data: data,
}).then(res=>{
if(res.data.code == 0){
//拿到的openid和session_key存到快取中
//呼叫換取使用者id介面[需求不同,可能介面會有相應的變化]
const url = '獲取使用者id的介面'
const data = {'要傳的資料'}
wepy.request({
url: url,
method: 'POST',
data: data,
}).then((res)=>{
//該介面設計返回的引數包括換取的使用者ID和返回的使用者的微信中資訊,也就是通過button獲取的那個userInfo[我們為了後續的處理,所以後臺這塊返回使用者資訊,如果使用者還未登入,使用者資訊,返回是空,反之則有值]
//儲存使用者ID
wx.setStorage({
key:'userId',
data:'獲取到的使用者ID'
})
//儲存使用者資訊[userInfo]
wx.setStorage({
key:'userInfo',
data:'獲取到的使用者資訊'
})
})
}
})
}
});
})
})
onShow(){
//從快取中獲取session_key
let skey = wx.getStorageSync('session_key');
if (!skey) {
//如果session_key不存在,再次執行登入
wx.login({
//該處登入同app.wpy[流程一樣]
});
}else{
// session_key存在
}
}
//我們假設這個頁面需要獲取使用者的資訊,首先給一個button[open-type設定為getUserInfo],使用這個拿到使用者的資訊,
getUserInfo(e){
this.userInfo = e.detail.userInfo; //e.detail.userInfo攜帶的就是使用者的個人資訊[包括頭像、暱稱等]
if(e.detail.userInfo){
wx.showToast({
title: '授權成功',
icon: 'success',
duration: 1500
})
//這裡做這樣的處理,是因為需求需要點選購物車按鈕跳轉訂單待支付頁,在沒有獲取到使用者資訊之前,跳轉購物車的按鈕隱藏,獲取使用者資訊按鈕顯示,反之則返
this.button = 'none'; //獲取使用者資訊button
this.myMenu = 'block'; //跳轉待支付訂單頁
//更新快取中的使用者資訊
wx.setStorage({
key:'userInfo',
data:this.userInfo
})
}else if(e.detail.errMsg == 'getUserInfo:fail auth deny'){
wx.showModal({
title: '提示',
content: '若不授權微信登入,則無法使用小程式。點選"授權"按鈕並允許使用"使用者資訊"方可正常使用。',
showCancel:false,
confirmText:'授權',
success:(res=>{
wx.openSetting({
success: (res) => {
}
})
})
})
}
}
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
對稱解密的目標密文為 Base64_Decode(encryptedData)。
對稱解密演算法初始向量 為Base64_Decode(iv),其中iv由資料介面返回。
signature = sha1( rawData + session_key )
//最終供外面呼叫的方法
function login(){
console.log('logining..........');
//呼叫登入介面
wx.login({
success: function (e) {
console.log('wxlogin successd........');
var code = e.code;
wx.getUserInfo({
success: function (res) {
console.log('wxgetUserInfo successd........');
var encryptedData = encodeURIComponent(res.encryptedData);
thirdLogin(code,encryptedData,res.iv);//呼叫伺服器api
}
})
}
});
}
function thirdLogin(code,encryptedData,iv){
var url = "eeee/xxx/login/ttttt";
var params = new Object();
params.code = code;
params.encryptedData = encryptedData;
params.iv =iv;
buildRequest(new Object(),url,params,{
onPre: function(page){},
onSuccess:function (data){
console.log('my login successd........');
console.log(data);
getApp().globalData.session_id = data.session_id;
getApp().globalData.uid = data.uid;
getApp().globalData.isLogin = true;
},
onError : function(msgCanShow,code,hiddenMsg){
}
}).send();
}