我的编程空间,编程开发者的网络收藏夹
学习永远不晚

微信小程序如何获取用户信息

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

微信小程序如何获取用户信息

我是IT果果日记,微信公众号请搜索 IT果果日记
一个普通的技术宅,定期分享技术文章,欢迎点赞、关注和转发,请多关照。
  • 微信小程序用户基本信息有哪些?

  • 除了基本信息,微信还会提供openId和unionId,它们有什么作用和区别?

  • 在获取用户信息的过程中,如何知道明文数据是否被篡改了?

  • session_key 该如何使用呢?

带着这些问题,我们开始今天的学习。

小程序提供了一个 wx.getUserProfile(OBJECT) 方法来获取用户的信息。以前的老版本是用的 wx.getUserProfile(OBJECT) 方法,现在以及被官方不推荐使用了。

用户信息分为用户基本信息和用户openId、UnionId。基本信息是明文的,而openId和UnionId是加密数据。这两种类型的数据都由wx.getUserProfile(OBJECT)方法返回。

用户基本信息包括以下7项:

  • avatarUrl 用户微信头像的URL地址。

  • city 城市。

  • country 国家。

  • gender 性别,1表示男,2表示女,0表示未知。

  • language 语言区域。

  • nickName 昵称。

  • province:省份。

在小程序中,用户的基本信息可以轻易获得,他们是明文的、不加密的。但 openId UnionId 是加密的。什么是openId和UnionId呢?可以将openId和UnionId理解为用户在微信应用中的id号。

他们的区别是:

  • openId只代表用户在某个微信应用下的id号;

  • 而UnionId是跨应用的,同一用户在同一开发者的多个应用里,UnionId是唯一的。

官方文档对于UnionId的描述非常清楚:如果开发者拥有多个移动应用、网站应用和公众账号(包括小程序),可通过UnionId区分用户的唯一性,因为只要是同一个微信开放平台账号下的移动应用、网站应用和公众账号(包括小程序),用户的UnionId就是唯一的。换句话说,同一用户在同一个微信开放平台下的不同应用中,UnionId是相同的。

所以,openId不能跨应用,如果要在多应用间统一用户身份,请使用UnionId。这里要注意,在小程序中使用UnionId首先需要前往微信开放平台绑定小程序。请参考官方文档:

https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html

微信开放平台绑定小程序流程

登录微信开放平台 — 管理中心 — 小程序 — 绑定小程序

微信开放平台绑定小程序

下面来看wx.getUserProfile(OBJECT)方法的使用。wx.getUserProfile的OBJECT参数有3个回调函数:success、fail和complete。在这3个回调函数中,重点介绍success。success方法的返回值有以下5个:

  • userInfo 用户基本信息对象,不包含openId等敏感信息。

  • rawData 不包含敏感信息的基本信息字符串,通常用来计算签名,防止从微信返回的用户信息被篡改。

  • signature 使用sha1(rawData+sessionkey)得到字符串,用于校验用户信息。

  • encryptedData 包括敏感数据在内的完整用户信息的加密数据。

  • iv 加密算法的初始向量。

现在,我们在代码中获取用户的明文信息。代码如下:

_getUserInfo: function() {var userInfoStorage= wx.getStorageSync(user);if (!userInfoStorage) {//如果缓存中没有用户信息,那么获取用户信息var that = this;wx.login({success: function (){wx.getUserProfile({success: function (res){that.globalData.userInfo = res.userInfo//将用户的基本信息保存到缓存中wx.setStorageSync('user',res.userInfo)},fail: function (res){console.log(res);}})}})}else {//如果缓存中已经存在用户的基本信息,那么将信息保存到全局变量中this.globalData.userInfo = userInfoStorage;}}

解释一下上述代码。为了避免每次启动小程序时都要在微信服务器中加载用户的基本信息,我们将用户信息保存到缓存中。这样,每次启动小程序时先去看看缓存有没有数据,如果没有,就调用wx.getUserProfile获取用户信息并保存到缓存和全局变量userInfo中;如果有,就直接将用户信息保存到全局变量userInfo里。

细心的朋友可能注意到,我们并不是直接调用wx.getUserProfile(OBJECT)方法,而是先调用wx.login,在wx.login调用成功后再继续调用wx.getUserProfile。之所以在wx.login调用成功后才调用wx.getUserProfile,是因为官方文档明确指出了获取用户信息需要先调用wx.login。同时,在官方的示例项目中也是先调用wx.login。至于wx.login有什么作用,请耐心的往下看,大家只需“依葫芦画瓢”,照做即可。

事实上,如果你只想获取用户的明文基本信息,那么不调用wx.login,直接调用wx.getUserProfile也可以获取用户信息。所以,是否在调用wx.getUserProfile前调用wx.login请大家自行决定。

当第一次运行以上代码并调用wx.getUserProfile时,小程序会弹出如图所示的提示窗口,让用户选择是否授权获取用户的基本信息。

用户授权获取信息

用户点击“允许”后,才会执行wx.getUserProfile的success回调函数,如果点击“拒绝”,将执行fail回调函数。

有些开发者在测试时可能永远不会弹出这个授权窗口。因为如果当前项目没有appId,那么用户信息是由微信模拟的信息,并没有进行真实的获取用户信息流程,所以不会出现这个窗口,且开发工具会有一个警告提示,如图所示。

没有appId时是开发工具模拟的用户数据

当然,这个用户数据也是真实的用户数据,因为你在使用开发工具时必须扫描二维码登录,这样开发工具就能知道你的微信身份,自然可以模拟返回你的用户数据。但模拟数据相比于真实的用户数据缺少3个属性,即signature、encryptedData和iv。也就是说,模拟数据只有明文信息而没有加密信息。

将用户信息保存到缓存中有一个缺点,就是没办法实时更新用户信息(比如用户更改了自己的微信资料),但这是具体业务的问题,需要开发者在实际项目编写中灵活处理。

上文已经介绍了如何调用微信登录接口以及获取用户信息。另外,在我以往的文章中也介绍了如何通过登录接口返回的code获取到session_key。之前提了一个问题,session_key是做什么用的呢?下面就讲解一下session_key的作用以及它的用法。

先来看看wx.getUserProfile返回的数据:

  • userInfo 用户基本信息对象,不包含openId等敏感信息。

  • rawData 不包含敏感信息的基本信息字符串,通常用来计算签名,防止从微信返回的用户信息被篡改。

  • signature 使用sha1(rawData+sessionkey)得到字符串,用于校验用户信息。

  • encryptedData 包括敏感数据在内的完整用户信息的加密数据。

  • iv 加密算法的初始向量。

我们使用了userInfo对象,包括userInfo和rawData在内的明文数据都可能存在被篡改的风险。如何知道明文数据是否被篡改了呢?

这个时候rawData和singature就可以发挥作用了。rawData和signature用于校验用户数据到底有没有被篡改过(没有绝对安全的网络,数据极有可能被抓包或者通过其他方式篡改)。通常来说,想要实现这个校验必须在服务器编码才能进行。这需要小程序将获取的rawData和signature一并提交到服务器,由服务器完成校验工作。

校验的基本原理是:rawData是用户原始明文数据,signature是使用sha1(rawData+sessionkey)得到的字符串。理论上讲,如果数据没有被篡改,那么signature等于sha1(rawData+sessionkey);如果rawData或者signature被修改了,那么signature必然不再等于sha1(rawData+sessionkey)。

是否存在signature和rawData同时被修改的情况呢?理论上是不可能的,因为session_key并不在网络上传输,篡改者不知道这个变量,被篡改且校验通过的概率很小。

有可能从signature中推算出session_key吗?理论上讲,这是不可能的。因为sha1算法是不可逆的,无法在已知rawData和signature的情况下推算出session_key。不知道session_key就无法通过同时修改rawData和signature达到“欺骗校验的目的”。如果知道了session_key,只需要修改rawData并重新用session_key计算一下新的sha1(rawData+session_key)就又可以让新的rawData等于新的sha1(rawData+session_key)了。这样,开发者就无法知道rawData是被修改过的。

这也是为什么官方文档一再强调,不要在网络上传输session_key,而应该将其保存在服务器上使用,以降低session_key被泄露的风险。

session_key有点类似于我们在数据库中保存用户密码时所使用的“盐(salt)”。在数据库保存用户密码时,并不是直接将用户的密码以明文的方式存放在数据库表中,通常都会使用SHA-1或者MD5算法将用户密码和salt随机字符串拼接在一起,重新计算一下再存入数据库中。被重新使用SHA-1或MD5算法计算的用户密码谁都不知道是什么,开发者也只能比对每次登录时输入的密码和数据库保存的密码是否一致,判断是否为合法用户,却无法知道密码到底是什么。

用户数据校验流程图

需要说明的是,我们明确说明服务器是没有保存session_key的。因为我们需要拿到session_key才能进行用户数据校验,所以在上述流程图再一次重复了用户的登录流程。在真实的流程中,用户登录在session_key的有效时间内只应该执行一次,session_key也应当被保存在服务器中。其实小程序只需要使用wx.request将rawData和signature发送到服务器即可,服务器无须使用code换取session_key,直接做SHA-1签名比对即可。如图所示为服务器已保存session_key的用户数据校验流程。

如果服务器已保存了session_key的用户数据校验流程

对比服务器没保存session_key和保存了session_key的数据校验流程图,很明显可以看出,服务器保存session_key后整个流程变得更加简单,完全不需要再与微信服务器交互。

服务器管理session_key的过程非常复杂,为了降低代码的复杂度,我们没有在服务器中保存session_key。我们后续的所有开放API调用流程都将重复完整的流程,因为单独完整的流程更加有利于开发者理解每个开放API。下面看下具体代码:

前端代码

wx.login({success: function (loginRes){wx.getUserProfile({success: function (userRes){wx.request({                    url: "http://localhost:8080/wxopen/wxcheckuserinfo"                    data: {                        code: loginRes.code,                        signature: userRes.signature,                        rawData: userRes.rawData                    },                    success: function(res){                        console.log(res.data);                    }                })}})}})

首先,登录并拿到code码,然后调用wx.getUserProfile接口到rawData和signature,再使用wx.request将这3个参数发送到服务器中,服务器会进行数据校验工作并返回校验结果。下面是服务器接口wxcheckuserinfo的编码。

Map map = new HashMap<>(7);map.put("appid",wxAppId);map.put("secret",wxSecret);map.put("js_code", param.getCode());map.put("grant_type",grantType);WxCode2SessionRet result = null;try{    String url = "https://api.weixin.qq.com/sns/jscode2session";    String info = HttpUtil.get(url, map);    result = JSON.parseObject(info, WxCode2SessionRet.class);} catch (Exception e){    log.error("code2session失败", e);    return null;}try {    String signature2 = DigestUtils.sha1Hex(encryptedData + result.getSession_key());    if (!signature.equals(signature2)) {        return R.error().message("签名校验失败");    }} catch (Exception e) {    throw new RuntimeException("用户信息校验失败");}

WxCode2SessionRet.java

@Datapublic class WxCode2SessionRet implements Serializable {    private String openid;    private String session_key;    private String unionid;    private String errcode;    private String errmsg;}

在以上代码中,首先使用code调用微信服务器换取session_key,随后使用session_key和signarue校验用户发送过来的rawData,最后返回校验结果。

建议开发者在客户端使用用户明文数据时使用rawData,而不要使用userInfo。因为数据验证的是rawData有没有被篡改,而不是验证userInfo是否被篡改。至于微信能否确保userInfo和rawData的一致性,这个不得而知。建议开发者使用rawData作为用户的基本信息。

至此,微信小程序获取用户信息、校验用户信息的过程就已经讲完了,下一篇文章我会介绍一下怎么解析用户的加密信息。

  • 用户基本信息有以下7个,他们属于明文

avatarUrl 用户微信头像的URL地址。
city 城市。
country 国家。
gender 性别,1表示男,2表示女,0表示未知。
language 语言区域。
nickName 昵称。
province:省份。

  • 用户加密信息有openId和UnionId,它们是用户在微信应用中的id号

他们的区别是:

1. openId只代表用户在某个微信应用下的id号;
2. 而UnionId是跨应用的,同一用户在同一开发者的多个应用里,UnionId是唯一的。

  • 如何知道明文数据是否被篡改了?通过校验用户加密信息rawData和signature是否一致。signature是使用sha1(rawData+sessionkey)得到的字符串。如果数据没有被篡改,那么signature等于sha1(rawData+sessionkey);如果数据被篡改,则不等于。

  • session_key有什么作用?session_key有点类似于我们在数据库中保存用户密码时所使用的“盐(salt)”。

我是IT果果日记,微信公众号请搜索 IT果果日记
一个普通的技术宅,定期分享技术文章,欢迎点赞、关注和转发,请多关照。

微信公众号 IT果果日记

https://gitee.com/chenzhaoplus

https://github.com/chenzhaoplus

https://blog.csdn.net/cz285933169?spm=1010.2135.3001.5421

来源地址:https://blog.csdn.net/cz285933169/article/details/128978495

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

微信小程序如何获取用户信息

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

微信小程序开发中如何获取用户信息

这篇文章主要为大家展示了微信小程序开发中如何获取用户信息,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“微信小程序开发中如何获取用户信息”这篇文章吧。wx.getUserInfo(OBJECT)获取
2023-06-26

小程序如何获取用户信息

这篇文章主要为大家展示了小程序如何获取用户信息,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“小程序如何获取用户信息”这篇文章吧。获取用户信息,withCredentials 为 true 时需要先
2023-06-26

微信小程序开发怎么获取用户信息

这篇文章主要介绍了微信小程序开发怎么获取用户信息的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇微信小程序开发怎么获取用户信息文章都会有所收获,下面我们一起来看看吧。第一中直接授权获取(在同一页面之中):首先在微
2023-06-29

微信小程序如何使用uni-app一键获取用户信息

本篇内容介绍了“微信小程序如何使用uni-app一键获取用户信息”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!用户不想输入账号密码,一键登录
2023-07-05

小程序开发如何获取用户信息

这篇“小程序开发如何获取用户信息”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“小程序开发如何获取用户信息”文章吧。有两种获取
2023-06-26

小程序如何获取用户信息失败

这篇文章主要介绍小程序如何获取用户信息失败,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!  在使用小程序时,很多人会不授权导致授权失败场景,但是小程序第二次不在启动授权信息弹层,遇到这种情况,为了用户体验我们需要这样
2023-06-26

微信小程序中如何获取系统信息

这篇“微信小程序中如何获取系统信息”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“微信小程序中如何获取系统信息”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢理解,接下来就让我们进入
2023-06-26

微信小程序获取用户openid

小程序端直接获取: 实现代码:直接简单 wx.login({ success(res) { if (res.code) { //发起网络请求 wx.request({
2023-08-17

微信小程序使用uni-app一键获取用户信息

这篇文章主要介绍了微信小程序使用uni-app一键获取用户信息,需要的朋友可以参考下
2023-01-28

IVX低代码平台——微信小程序获取用户信息

写在前面 小程序可以通过方便地获取微信提供的用户身份标识,快速建立小程序内的用户体系。本文将向大家展示低代码开发:小程序实现获取用户信息的方法,供大家参考。 文章目录 写在前面开发概述准备工作用户组件发起小程序登录用户组件获
2023-08-17

微信小程序中如何使用wx.getImageInfo()获取图片信息

本文将为大家详细介绍“微信小程序中如何使用wx.getImageInfo()获取图片信息”,内容步骤清晰详细,细节处理妥当,而小编每天都会更新不同的知识点,希望这篇“微信小程序中如何使用wx.getImageInfo()获取图片信息”能够给
2023-06-26

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录