微信小程序授权获取用户手机号及后端解密

 

小程序在拉取用户授权的时候获取用户手机号,前端获取后后端解密就可以存到数据库了。

1.getPhoneNumber这个组件通过button来实现(别的标签无效)。将button中的open-type=“getPhoneNumber”,并且绑定bindgetphonenumber事件获取回调。

2.在使用这个组件之前必须先调用login接口,如果没有调用login点击button时会提示先调用login。


App({  
    onLaunch: function () {  
        wx.login({  
            success: function (res) {  
                if (res.code) {  
                    //发起网络请求  
                    console.log(res.code)  
                } else {  
                    console.log('获取用户登录态失败!' + res.errMsg)  
                }  
            }  
        });  
    }  
})

注意

在回调中调用 wx.login 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。
 

3.通过bindgetphonenumber绑定的事件来获取回调。回调的参数有三个,

errMsg:用户点击取消或授权的信息回调。

iv:加密算法的初始向量(如果用户没有同意授权则为undefined)。

encryptedData: 用户信息的加密数据(如果用户没有同意授权同样返回undefined)

getPhoneNumber(e) {
    let CONST = app.$.CONST
    let appid = CONST.APPID
    let secret = CONST.APPSECRET
    let grant_type = 'authorization_code'
    let encryptedData = e.detail.encryptedData
    let iv= e.detail.iv
    wx.login({
      success(res){
        wx.request({
          url: 'https://api.weixin.qq.com/sns/jscode2session?appid=wx8493c38c2f678a82&secret=57bfc41d2101a3a517b2bd7dec399803&js_code=' + res.code +'&grant_type=authorization_code',
          success(r) {
            let session_key = r.data.session_key
            request({
              url: “后端处理解密的API”,
              data:{
                id:app.$.info.id,//这个是当前用户的ID,便于存到数据库
                session_key,
                encryptedData,
                iv,
                appId:appid
              },
              success:res=>{

                console.log(res)
              }
            })
          }
        })
      }
    })
  },

4.后端解密API(js),按官方文档来

  const crypto = require('crypto')
  module.exports = async(ctx, next) => {
    let {
      iv,
      encryptedData,
      session_key,
      appId,
      id
    } = ctx.request.body
    function WXBizDataCrypt(appId, session_key) {
      this.appId = appId
      this.session_key = session_key
    }

    WXBizDataCrypt.prototype.decryptData = function(encryptedData, iv) {
      // base64 decode
      var session_key = new Buffer(this.session_key, 'base64')
      encryptedData = new Buffer(encryptedData, 'base64')
      iv = new Buffer(iv, 'base64')

      try {
        // 解密
        var decipher = crypto.createDecipheriv('aes-128-cbc', session_key, iv)
        // 设置自动 padding 为 true,删除填充补位
        decipher.setAutoPadding(true)
        var decoded = decipher.update(encryptedData, 'binary', 'utf8')
        decoded += decipher.final('utf8')

        decoded = JSON.parse(decoded)

      } catch (err) {
        throw new Error('Illegal Buffer')
      }

      if (decoded.watermark.appid !== this.appId) {
        throw new Error('Illegal Buffer')
      }

      return decoded
    }
    let pc = new WXBizDataCrypt(appId, session_key)
    let data = pc.decryptData(encryptedData, iv)
    return ctx.db('User')
      .update({
        phoneNum: data.phoneNumber
      }).where({
        id
      }).then(r =>{
        console.log(r)
        ctx.body = data
      })
      .catch(err=>{
        console.error(err)
      })
  }

5.至此返回的数据就是用户手机号了,中间的业务逻辑还是去看下官方文档的,这里说的不好,只是大概的逻辑是这样。

你可能感兴趣的:(小程序)