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

 

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

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

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber" 
   >立即绑定</button>

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

 

这里推荐一个公众号:前端进阶栈,里面不少干货,让我们一起学习,一起进步。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
微信小程序获取用户手机号需要前端进行授权后端需要进行解密。以下是完整代码: 前端代码: ``` wx.login({ success: function (res) { if (res.code) { wx.request({ url: 'https://yourdomain.com/onLogin', data: { code: res.code }, success: function (res) { if (res.data.code === 0) { wx.setStorageSync('token', res.data.data.token); wx.getUserInfo({ success: function (res) { wx.request({ url: 'https://yourdomain.com/onGetUserInfo', data: { encryptedData: res.encryptedData, iv: res.iv }, header: { 'Authorization': 'Bearer ' + res.data.data.token }, success: function (res) { console.log(res.data); } }) } }) } else { console.log('登录失败!' + res.errMsg) } } }) } else { console.log('获取用户登录态失败!' + res.errMsg) } } }) ``` 后端代码: ``` <?php namespace app\api\controller; use think\Controller; use think\Request; use app\api\model\User as UserModel; use app\api\service\Token as TokenService; use app\api\service\WxUser as WxUserService; class User extends Controller { public function login() { $code = input('post.code'); $wxUser = new WxUserService($code); $openid = $wxUser->getOpenId(); $user = UserModel::getByOpenId($openid); if (!user) { $user = UserModel::create([ 'openid' => $openid ]); } $token = TokenService::generateToken(); TokenService::saveToCache($token, $user->id); return [ 'code' => 0, 'data' => [ 'token' => $token ] ]; } public function getUserInfo() { $encryptedData = input('post.encryptedData'); $iv = input('post.iv'); $token = TokenService::getCurrentToken(); $uid = TokenService::getUidByToken($token); $user = UserModel::get($uid); $wxUser = new WxUserService(); $wxUser->setSessionKey($user->session_key); $wxUserInfo = $wxUser->getUserInfo($encryptedData, $iv); $user->saveUserInfo($wxUserInfo); return [ 'code' => 0, 'data' => $wxUserInfo ]; } public function getPhoneNumber() { $encryptedData = input('post.encryptedData'); $iv = input('post.iv'); $token = TokenService::getCurrentToken(); $uid = TokenService::getUidByToken($token); $user = UserModel::get($uid); $wxUser = new WxUserService(); $wxUser->setSessionKey($user->session_key); $phoneNumber = $wxUser->getPhoneNumber($encryptedData, $iv); $user->savePhoneNumber($phoneNumber); return [ 'code' => 0, 'data' => $phoneNumber ]; } } ``` 其中,WxUserService是一个封装了微信小程序登录和解密的服务类,UserModel是一个用户模型类,TokenService是一个封装了Token生成和验证的服务类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值