作者:sichen
原文链接:https://segmentfault.com/a/1190000015281442
最近因为公司业务一直在做微信小程序的项目,趁此机会将最近踩过的一些坑总结记录下
微信小程序登陆流程
前端调用wx.login(),获取临时登录凭证 code
通过wx.request()将code发给服务器(需要后端创建接口接收code)
后端进行登录凭证校验,入参为(appid,secret,js_code,grant_type)
appid 小程序唯一标识
secret 小程序的 app secret
js_code 登录时获取的 code
grant_type 填写为 authorization_code
登陆凭证校验通过,从微信服务器换取openid和session_key
openid 用户唯一标识
session_key 会话密钥openid 是用户唯一标识,但不建议直接用做后端服务器的各用户标示符。
session_key 是针对用户数据进行加密签名的密匙。session_key 在文件校验,获取用户具体信息时均需使用一般为了安全起见,这两个数据都不会发往客户端。
后端将session_key处理之后,返回前端一个处理后的一个字符串作为用户的登陆标识,一般以token的形式。(自定义登陆态与openid session_key相关)
前端接收到token,储存到localStorage中,每次向服务器请求数据的时候带上,作为服务器识别用户的凭证。
后续用户进入小程序时,首先调用 wx.checkSession() 检测登陆态,如果失败,重新发起登陆流程。
//app.jsconst NOLOGINCODE = 1000003 //未登录const SUCCESS = 1000001 //成功App({ onLaunch: function () { var loginFlag = wx.getStorageSync('sessionId'); var that = this; if (loginFlag) { // 检查 session_key 是否过期
wx.checkSession({ // session_key 有效(未过期)
success: function () { var userInfo = wx.getStorageSync('wxUserInfo') if (userInfo) {
that.globalData.hasUserInfo = true
}
}, // session_key 过期
fail: function () { // session_key过期,重新登录
that.doLogin();
}
});
} else { // 无skey,作为首次登录
this.doLogin();
}
},
doLogin() { this.log().then(res => { this.$post('/auth', { code: res.code, }, false).then(data => {
wx.setStorageSync('sessionId', data.sessionId);
})
})
}, /**
*微信登录 获取code值,并将code传递给服务器
* @returns
*/
log() { return new Promise(resolve => {
wx.login({
success(res) { if (res.errMsg === "login:ok") {
resolve(res)
} else {
wx.showToast({ title: '微信登录失败', icon: 'none', duration: 1200
})
}
},
fail() {
wx.showToast({ title: '微信登录接口调用失败', icon: 'none', duration: 1200
})
}
})
})
}, globalData: { baseurl: 'https://www.fake.shop'
}
})补充
微信小程序中网络请求的api是wx.request(),但是这个请求是个异步回调的形式,每次发请求都要写好长一串,而且如果是嵌套的发请求,就会发现代码写的及其臃肿,所以将其 Promisefy是及其有必要的。
代码如下:
$get(url, data = {}, needToken = true) { let SUCCESS = 200
var that = this
needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
return new Promise((resolve, reject) => {
wx.request({ url: that.globalData.baseurl + url, method: "GET", header: { 'content-type': 'application/json'
}, data: data,
success(e) { if (e.data.code == SUCCESS) {
resolve(e.data) return
}
},
fail(e) {
wx.showModal({ title: '提示', content: '请求失败', showCancel: false
})
reject(e)
}
})
})
},
$post(url, data = {}, needToken = true) { let that = this
let SUCCESS = 200
let TimeOut = 1000
var that = this
needToken ? (data.token = wx.getStorageSync('ToKen')) : ''
return new Promise((resolve, reject) => {
wx.request({ url: that.globalData.baseurl + url, method: "POST", //此处可以根据接口文档设置header头
// header: {
// 'content-type': 'application/x-www-form-urlencoded'
// },
data: data,
success(e) { if (e.statusCode == SUCCESS) { if (e.data.code == SUCCESS) {
resolve(e.data)
} else {
reject(e)
wx.showModal({ title: '提示', content: e.data.msg, showCancel: false, success: function (res) { if (res.confirm) { if (e.data.code == TimeOut) { //根据实际业务返回的code码判断是否过期
// 登录过期
that.doLogin();
}
}
}
})
}
} else {
wx.showModal({ title: '提示', content: e.data.error, showCancel: false
})
reject(e)
}
},
fail(e) { console.log(e)
wx.showModal({ title: '提示', content: '请求失败', showCancel: false
})
reject(e)
},
complete(e) {
}
})
})
},先这么多吧,好累啊,溜了溜了,剩下的留着以后更

随时随地看视频