不知不觉已经一个月没有写东西了,堕落的日子竟然过的这么心(chou)安(bu)理(yao)得(lian),罪过啊。javascript
好了,回到正文来,聊我们的小程序。css
登陆大部分逻辑代码通通来自手把手教会你小程序登陆鉴权前端
上图是官方给出的登陆流程,咱们来捋下逻辑。java
一、用户使用wx.login
获取临时code
,有效期为5分钟git
二、将临时code
传到咱们本身的后端服务,调用微信的API获取用户的session_key
和openid
github
三、后端自定义新的密钥并关联返回的session_key
和openid
,将新的密钥返给前端ajax
四、前端发送请求的时候,带着密钥,后端进行解析后返回数据算法
一、session_key
会话密钥,用来肯定会话的操做的有效性和用来加密解密用户数据,服务器本身存储便可,不该该将密钥返给前端和对话使用数据库
二、openid
用户惟一标识,一样只用于服务器,能够用来标识用户的惟一性编程
接下来,咱们说下它们的获取,经过服务端调用微信API获取
API:https://api.weixin.qq.com/sns/jscode2session
参数以下:
// 小程序页面 wx.login({ success:(ret)=>{ wx.request({ url: 'http://test.com', // 后端服务器 data:{ code : ret.code } }) } })
后端服务咱们使用request
模块来发送请求
// 后端服务 let options = { url: 'https://api.weixin.qq.com/sns/jscode2session', qs:{ appid: appid, secret: secret, js_code: code, grant_type:'authorization_code' } } // 默认请求方式是get request(options, (err, response, body) => { if(err) return err return body // {openid:'openid', session_key:'session_key'} 不是真正的返回 看下面的代码 })
上面咱们获取了session_key和openid,下文两个字断称keyID,接下来咱们生成一个新的密钥返回前端并将新密钥关联keyID。
咱们使用crypto模块的sha1算法生成密钥
const crypto = require('crypto') function getShaKey(data){ return crypto.createHash('sha1').update(data, 'utf8').digest('hex') }
上面的代码返回咱们就改为这个新的skey,前端将这个密钥存在storage里面,请求的时候带上这个skey,就完成了自定义登陆态。
用来校验当前用户的session_key是否有效,微信不会把session_key的有效期告知开发者,用户越频繁使用小程序,session_key有效期越长。
wx.checkSession({ success:function(){ // 当前session_key有效 ... // 能够写咱们的业务代码 }, fail:function(){ // 当前session_key已过时 wx.login() // 从新登陆,获取新的session_key } })
当session_key过时的时候,咱们调用登陆API,更新session_key生成新的skey,并关联两者关系。
前面咱们将流程大概串了下,接下来咱们把上面的流程写成写成公用的函数
// 验证session_key状态 function checkSession(){ return new Promise((resolve, reject) => { wx.checkSession({ success:function(){ resolve(true) }, fail:function(){ reject(false) } }) }) } // 登陆 function login(){ return new Promise((resolve, reject) => { wx.login({ success: (ret) => { wx.request({ url:'本地服务地址', method: 'POST', data:{ code: ret.code }, success: (response) =>{ wx.setStorageSync('skey', response.data.key) // 将skey存在storage里面 resolve(response.data.key) } }) } }) }) } // 请求 function ajax(url, data, method="GET", config={}){ let skey = wx.getStorageSync('skey') // 获取skey if(!skey){ // 没有skey,首次登陆 return new Promise((resolve, reject) => { login() reject('请登陆') }) } else { return new Promise((resolve, reject) => { checkSession().then( _=> { if (_){ // session_key有效 wx.request({ url, method: method.toLocaleUpperCase(), data, header: Object.assign({}, { skey }, config), success: (ret) => { resolve(ret.data) } }) } else { // session_key失效 login() reject('session_key失效') } }) }) } }
后端使用koa框架,代码见文末github
地址
官方提供了多种编程语言的示例代码点击下载
这里咱们使用微信运动API为例
var app = getApp() // 咱们将工具函数都放在了app的示例上面 Page({ onLoad:function(){ app.Util.login().then(_ => { // 先登陆而后获取数据 this.getrunData() }) }, getrunData(){ wx.getWeRunData({ success: (ret) => { app.Util.ajax('本地服务地址', { iv: ret.iv, data: ret.encryptedData}, 'post').then(_=>{ console.log(_) }, (err)=>{ console.log(err) }) } }) }, })
返回结果以下
以上,咱们完成了小程序简单的登陆鉴权和数据解密
登陆鉴权咱们只是将用户状态放在了内存里,实际项目中确定要放在数据库中,能够拜读下大神文章,里面说到了数据库的操做。
再次致敬
本文完整代码请戳github