个人博客 个人博客
首页
  • 前端
  • 后端
  • Git
  • Docker
  • 网络
  • 操作系统
工具
阅读
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

董先亮

前端react开发
首页
  • 前端
  • 后端
  • Git
  • Docker
  • 网络
  • 操作系统
工具
阅读
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Taro

    • 获取用户信息
      • 1. 微信登录
      • 2. 获取用户信息
        • 2.1 只获取用户openid
        • 2.2 获取昵称、头像、openid等更多信息
        • 2.3 微信获取用户信息接口调整
      • 3. 获取用户手机号
      • 4. 关于解密
        • 4.1 sessionKey
        • 4.2 node版本解密demo
    • 开发常见问题
    • 页面间通信
    • taro-vue实现样式穿透
    • 小程序服务通知
    • taro实现上拉下拉
    • taro转app
    • 设计稿尺寸选择
  • uni

  • 小程序
  • Taro
NeverStop1024
2022-12-05
目录

获取用户信息

# 1. 微信登录

  1. 调用wx.login(Object object)接口地址 (opens new window)拿到code,
  2. 将code传给后端,后端调auth.code2Session (opens new window)获取openid、session_key
  3. 登录成功、开发者自定义存储登录状态(用户无感)

# 2. 获取用户信息

# 2.1 只获取用户openid

调用wx.getUserInfo (opens new window),拿到encryptedData,后端自行解密,解密成功后将openid返回给客户端。(用户无感)

# 2.2 获取昵称、头像、openid等更多信息

调用wx.getUserProfile(Object object) (opens new window),需弹出用户授权,同意后拿到encryptedData,发给后端进行解密。(用户有感)

# 2.3 微信获取用户信息接口调整

小程序登录、用户信息相关接口调整说明 (opens new window)

# 3. 获取用户手机号

  1. 获取用户手机号需用户主动触发(文档 (opens new window)),拿到encryptedData(手机号加密数据)、iv
  • 注意: 获取手机号需完成认证,开发阶段拿测试号可以走完完整流程
<nut-button open-type="getPhoneNumber" @getphonenumber="wxLogin" type="primary" style="width: 100%">获取手机号</nut-button>

const wxLogin = (res) => {
  console.log('获取手机号成功',res)
}
1
2
3
4
5
  1. 登录拿到session_key
  2. 后端将encryptedData解密出手机号,返回给客户端

参考: 微信小程序获取用户手机号 (opens new window)

# 4. 关于解密

# 4.1 sessionKey

  • 客户端获取到的用户信息、用户手机号等信息大部分都是加密数据encryptedData,需要后端解密后才能使用。
  • 后端解密都需要sessionKey,前端登录完,换取的sessionKey可以存起来,需要的时候传给后端,不用每次用都得重新调用wx.login重新换取。
  • 重新换取sessionKey后,上一个sessionKey可能会失效。

sessionKey的验证

  • 每次向后端发送sessionKey前,可以先走wx.checkSession (opens new window)是否还有效

# 4.2 node版本解密demo

解密算法 (opens new window),根据官方提供的解密流程,提供了几个封装好的示例。

// demo.js
var WXBizDataCrypt = require('./WXBizDataCrypt')

var appId = 'wx4f4bc4dec97d474b'
var sessionKey = 'tiihtNczf5v6AKRyjwEUhQ=='
var encryptedData = 
	'CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZM'+
	'QmRzooG2xrDcvSnxIMXFufNstNGTyaGS'+
	'9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+'+
	'3hVbJSRgv+4lGOETKUQz6OYStslQ142d'+
	'NCuabNPGBzlooOmB231qMM85d2/fV6Ch'+
	'evvXvQP8Hkue1poOFtnEtpyxVLW1zAo6'+
	'/1Xx1COxFvrc2d7UL/lmHInNlxuacJXw'+
	'u0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn'+
	'/Hz7saL8xz+W//FRAUid1OksQaQx4CMs'+
	'8LOddcQhULW4ucetDf96JcR3g0gfRK4P'+
	'C7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB'+
	'6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns'+
	'/8wR2SiRS7MNACwTyrGvt9ts8p12PKFd'+
	'lqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYV'+
	'oKlaRv85IfVunYzO0IKXsyl7JCUjCpoG'+
	'20f0a04COwfneQAGGwd5oa+T8yO5hzuy'+
	'Db/XcxxmK01EpqOyuxINew=='
var iv = 'r7BXXKkLb8qrSNn05n0qiA=='

var pc = new WXBizDataCrypt(appId, sessionKey)

var data = pc.decryptData(encryptedData , iv)

console.log('解密后 data: ', data)
// 解密后的数据为
// data = {
//   "nickName": "Band",
//   "gender": 1,
//   "language": "zh_CN",
//   "city": "Guangzhou",
//   "province": "Guangdong",
//   "country": "CN",
//   "avatarUrl": "http://wx.qlogo.cn/mmopen/vi_32/aSKcBBPpibyKNicHNTMM0qJVh8Kjgiak2AHWr8MHM4WgMEm7GFhsf8OYrySdbvAMvTsw3mo8ibKicsnfN5pRjl1p8HQ/0",
//   "unionId": "ocMvos6NjeKLIBqg5Mr9QjxrP1FA",
//   "watermark": {
//     "timestamp": 1477314187,
//     "appid": "wx4f4bc4dec97d474b"
//   }
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// WXBizDataCrypt.js
var crypto = require('crypto')

function WXBizDataCrypt(appId, sessionKey) {
  this.appId = appId
  this.sessionKey = sessionKey
}

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

  try {
     // 解密
    var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, 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
}

module.exports = WXBizDataCrypt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
编辑 (opens new window)
上次更新: 2022/12/29
开发常见问题

开发常见问题→

最近更新
01
mock使用
07-12
02
websocket即时通讯
07-12
03
前端面试题
07-09
更多文章>
Theme by Vdoing | Copyright © 2022-2023 NeverStop1024 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式