微信小程序里获取用户信息,核心 API 就是 wx.getUserInfoOBJECT(实际开发中通常写作 wx.getUserInfo(Object object))。它接收一个对象参数,用来控制是否携带登录态、指定超时时间,并在回调里返回用户资料。不过现在直接调用这个接口并不会弹出授权框,返回结果里的 userInfo 往往是匿名数据,头像和昵称可能显示为默认的灰色头像和“微信用户”。要拿到真实昵称、头像、性别、省份等信息,必须理解它的触发时机与用户授权机制。

参数结构与回调数据拆解
wx.getUserInfo(Object object) 的 object 参数包含几个常用字段:withCredentials、lang、success、fail、complete。其中 withCredentials 默认是 false,表示是否带上登录态信息。如果设为 true,返回结果中会包含 signature 和 encryptedData 等加密数据,用来在服务端校验用户身份。普通前端展示场景不需要开启,但涉及用户资料解密或多端登录态校验时可以配合后端做签名比对。
实际开发中比较容易忽略的是 lang 字段。它支持 en、zh_CN、zh_TW 等值,影响返回语言。默认值跟随系统,如果用户系统是英文,昵称和地区信息可能返回英文格式。若你的小程序界面锁定中文,最好显式传 lang: 'zh_CN'。基础库 2.1.0 以后还增加了 timeout,单位毫秒,用来给接口设置超时时间,超时后触发 fail 回调。
返回值方面,旧版本会完整返回 userInfo 对象,包含 nickName、avatarUrl、gender、country、province、city、language 等字段。现在则分两种场景:如果用户已经授权,可以从回调里拿到真实信息;如果没有授权,则拿到默认匿名信息。因此不能仅凭调用成功就认为获取到了真实昵称,需要进一步判断 res.userInfo.nickName 是否为默认值。
wx.getUserInfo({
withCredentials: true,
lang: 'zh_CN',
timeout: 3000,
success: function(res) {
console.log('用户信息:', res.userInfo)
console.log('签名串:', res.signature)
},
fail: function(err) {
console.error('调用失败:', err.errMsg)
}
})
授权弹窗与 button 组件配合
早期小程序里,开发者可以直接在页面加载时调用 wx.getUserInfo,首次会弹出系统授权框。但从某次基础库调整后,这一行为被取消,必须由用户主动点击按钮才能触发授权。具体做法是在页面中放置一个 <button> 组件,并设置 open-type="getUserInfo",再通过 bindgetuserinfo 绑定回调函数。用户点击后,微信会弹出授权提示,用户允许或拒绝的结果会在回调事件 e.detail 中给出。
这样做的好处是避免了页面刚进入就弹窗影响体验,也符合微信对隐私合规的要求。坏处是交互链路变长,有些用户可能不愿意点击按钮,导致后续业务无法拿到身份信息。因此按钮文案要写得清楚,例如“授权并登录”比单纯的“获取资料”更有引导性。
<view class="auth-area"> <button open-type="getUserInfo" bindgetuserinfo="handleGetUserInfo">授权并登录</button> </view>
对应的 JS 处理逻辑并不复杂。回调事件对象 e.detail.userInfo 就是用户资料。但要注意,用户拒绝授权时 e.detail.userInfo 为 undefined,同时 e.detail.errMsg 会返回类似 getUserInfo:fail auth deny 的信息。这时应提示用户重新授权,而不是直接把失败原因抛给用户。可以根据需要将信息存入全局状态或调用后端接口绑定登录态。
Page({
data: {
userInfo: null
},
handleGetUserInfo: function(e) {
if (e.detail.userInfo) {
this.setData({
userInfo: e.detail.userInfo
})
wx.showToast({
title: '授权成功',
icon: 'success'
})
} else {
wx.showModal({
title: '提示',
content: '你拒绝了授权,暂无法获取资料',
showCancel: false
})
}
}
})
从 wx.getUserInfo 到 wx.getUserProfile 的演进
随着基础库版本提升,微信推出了 wx.getUserProfile 接口,取代原先的按钮授权方式。这个接口必须在用户点击事件的回调中同步调用,例如按钮的 tap 事件触发后立即执行,不能放在异步函数里延迟调用,否则会报 fail。与 wx.getUserInfo 相比,它不再依赖 button 的 open-type,而是允许使用普通按钮,但每次调用都会弹窗征求用户同意。
wx.getUserProfile 的参数包含必填的 desc 字段,用于说明获取用户信息的目的。这个说明会显示在授权弹窗中,不能为空。例如填写“用于展示个人头像和昵称”。成功回调中同样返回 userInfo 对象,字段结构与旧接口保持一致。需要注意的是,该接口不能频繁调用,同一用户在同一时刻只能有一个授权弹窗,否则会失败。
getUserProfile: function() {
wx.getUserProfile({
desc: '用于完善会员资料',
success: function(res) {
console.log(res.userInfo)
},
fail: function(err) {
console.error(err.errMsg)
}
})
}
对于需要兼容旧版本的项目,可以同时保留两种方案。在页面中通过 wx.getUserProfile 是否存在来判断基础库版本。若存在则使用新接口;否则继续使用 button 的 open-type="getUserInfo"。这样既满足新版审核要求,也不会让老用户无法使用。判断代码可以写在按钮点击函数里,避免重复弹窗。
handleUserAuth: function() {
if (wx.getUserProfile) {
wx.getUserProfile({
desc: '用于登录和展示头像昵称',
success: function(res) {
console.log(res.userInfo)
}
})
} else {
wx.getUserInfo({
success: function(res) {
console.log(res.userInfo)
}
})
}
}
常见报错与排查思路
调用 wx.getUserInfoOBJECT 时最常遇到的错误是 getUserInfo:fail auth deny,这表示用户拒绝了授权。不要一看到 fail 就认为代码写错。可以通过 wx.getSetting 查询当前用户是否已经关闭了用户信息授权。若用户曾拒绝且没有重新触发授权入口,后续调用会一直失败。此时应引导用户去右上角菜单或设置页开启权限,但更推荐提供一个重新授权的按钮。
另一个问题是开发者工具中调试正常,真机上却拿不到数据。这多半是因为没有在真机上重新点击授权,或者使用了基础库版本较低的测试机。开发者工具可以模拟授权,但真机环境更严格。遇到这种情况,先检查 wx.getSetting 里 scope.userInfo 的状态,并在真机上删除小程序重新进入,清空授权缓存后再测试。
wx.getSetting({
success: function(res) {
if (res.authSetting['scope.userInfo']) {
wx.getUserInfo({
success: function(info) {
console.log(info.userInfo)
}
})
} else {
wx.showModal({
title: '授权提示',
content: '需要你确认用户信息权限',
showCancel: false
})
}
}
})
如果涉及服务端解密,encryptedData 和 iv 要与 code 一起传给后端,通过 jscode2session 获取 session_key 后解密。不要把 session_key 写到前端或日志中。签名 signature 可以通过 SHA1 校验 rawData 与 session_key 的对应关系,作为防篡改手段。这些属于用户信息安全的延伸部分,适合在需要构建稳定账号体系时使用。掌握好参数结构、授权流程以及新旧接口差异,基本就能覆盖大多数微信小程序用户信息相关的业务场景。

