简单走一遍流程,主要学习怎么加密解密那一套
实战项目: https://github.com/klren0312/ironInfoWeapp/blob/master/ApiServer/app/controller/weapp.js
使用技术
- 服务端:egg.js 2.x
- 客户端:微信小程序
参考资料
- 小程序登录文档:https://developers.weixin.qq.com/miniprogram/dev/api/api-login.html
- 小程序签名加密文档:https://developers.weixin.qq.com/miniprogram/dev/api/signature.html
- 手把手教会你小程序登录鉴权:https://juejin.im/post/5ac9b72cf265da23906c486a
流程想法
2018.4.18 想法
小程序端
页面加载时检测session,若失效则重新登录,并将获取的skey存入localStorage
login.wxml
<button bindtap='login'>login</button>
login.js
Page({
onLoad: function (options) {
wx.checkSession({
success: function (v) {
console.log(v)
},
fail: function (v) {
console.log(v)
this.login()
}.bind(this)
})
},
login: function() {
wx.login({
success: (loginRes) => {
wx.getUserInfo({
success: function (rawData) {
let { encryptedData, iv, signature } = rawData;
wx.request({
url: 'http://localhost:7001/weapp',
method: 'POST',
data: {
'crypted': encryptedData,
'iv': iv,
'signature': signature,
'code': loginRes.code
},
success: (res) => {
wx.setStorage({
key: 'skey',
data: res.data.skey,
})
}
})
}
})
}
})
}
})
开发者服务端
通过code获取session_key
通过小程序的wx.login()获取到的code,来请求微信官方登录接口,获取到session_key
async getSessionKey(code) {
let appid = 'wxefe389c79a8fec0f';
let secret = '1d72d78208549bbe21bf4d9a40736f7e';
let grant_type = 'authorization_code';
let wecode = code;
// 登录接口地址
let url = `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${wecode}&grant_type=${grant_type}`;
// 请求登录接口
const result = await this.app.curl(url,{
dataType:'json'
});
return result.data.session_key;
}
解密函数
使用小程序发送过来的iv和获取到的session_key来解密加密的数据encryptedData
function decodeUserInfo(key,iv,crypted) {
crypted = new Buffer(crypted, 'base64')
key = new Buffer(key, 'base64')
iv = new Buffer(iv, 'base64')
const decipher = crypto.createDecipheriv('aes-128-cbc', key, iv)
let decoded = decipher.update(crypted, 'base64', 'utf8')
decoded += decipher.final('utf8')
return decoded
}
加密session_key函数
还需要将session_key加密后发送给客户端留存,原理就相当于一个token,用来请求开发者服务端的相关数据。
function encryptSha1(data) {
return crypto.createHash('sha1').update(data,'utf8').digest('hex');
}
登录函数
将上面几个方法串起来,暂时没写存数据库的逻辑
async login() {
let {ctx} = this;
let {crypted,iv,signature,code} = ctx.request.body;
let key = await this.getSessionKey(code);
// 加密session_key 传给客户端
let skey = encryptSha1(key)
// 解密用户信息,可以将其存入数据库
let decode = JSON.parse(decodeUserInfo(key,iv,crypted))
ctx.body = {
skey: skey
}
}
代码地址
服务端:
- https://github.com/klren0312/weapp_login_study/blob/master/app/controller/weapp.js
- https://github.com/klren0312/weapp_login_study/blob/master/app/router.js
小程序端: