微信小程序登录并获取用户信息
1.概述
详细介绍微信小程序登录功能的实现流程,包括前端获取临时登录凭证、用户信息,以及后端通过凭证换取用户唯一标识(openid)、会话密钥(session_key)并处理用户信息的完整过程
2.核心流程
1. 前端通过wx.login()获取临时登录凭证(code)
2. 前端通过wx.getUserinfo( )/wx.getUserProfile()获取用户基础信息(昵称、头像等)
3. 前端将 code 和用户信息发送至后端接口
4. 后端接收 code,调用微信官方code2Session接口换取 openid 和 session_key
5. 后端处理用户信息(如存储到数据库),生成自定义登录态(token)返回给前端
6. 前端保存登录态,完成登录流程
7.登录流时序图

|
凭证/信息 |
位置 |
作用 |
有效期 |
|
code |
小程序前端获取 |
一次性凭证,用于向服务器换取 openid 和 session_key |
5分钟 |
|
openid |
后端服务器 |
用户在小程序内的唯一标识,用于区分用户 |
永久 |
|
session_key |
后端服务器 |
会话密钥,用于解密微信返回的敏感数据 |
动态变化 |
|
unionid |
后端服务器 |
用户在开放平台账号下的统一标识,用于打通不同应用 |
永久 |
3.前端实现
(1)wx.getUserinfo()/wx.getUserProfile()的区别
wx.getUserinfo()只能在用户点击 button 组件(open-type="getUserInfo") 时触发授权
getUserProfile 并不需要像 getUserInfo 依赖 button 组件的 open-type 属性,它可以直在 JavaScript 代码中调用
(2)前端登录
小程序页面(如pages/index/index.vue)中添加一个用于触发登录的按钮。这个按钮应使用<button>标签,并设置open-type="getUserInfo"来触发用户信息的获取。同时,绑定一个处理函数(如getUserInfo)来响应用户的授权行为。
<template>
<view>
<button open-type="getUserInfo" @getuserinfo="getUserInfo">微信登录</button>
</view>
</template>
<button bindtap="getUserInfoHandler" class="login-btn">获取用户信息</button>
编写getUserInfo方法来处理用户的授权信息。如果用户同意授权,则调用uni.login方法获取登录凭证(code),并将该code发送到后端服务器。
export default {
methods: {
/**
* 处理用户信息授权事件
* @param {Object} e - 事件对象,包含用户授权信息
*/
getUserInfo(e) {
// 判断用户是否允许授权
if (e.detail.userInfo) {
// 用户允许授权,获取用户信息
const userInfo = e.detail.userInfo
console.log('用户授权成功,用户信息:', userInfo)
//用户信息处理方式,3种
// 1. 保存到本地存储
wx.setStorageSync('userInfo', userInfo)
wx.showToast({
title: '授权成功',
icon: 'success',
duration: 200
})
//2 . 可以将用户信息发送到后端结合code获取openId
this.sendUserInfoToServer(userInfo)
} else {
// 用户拒绝授权
console.log('用户拒绝授权')
wx.showToast({
title: '请授权以继续使用',
icon: 'none',
duration: 200
})
}
},
/**
* 3.将用户信息发送到服务器
* @param {Object} userInfo - 用户信息对象
*/
sendUserInfoToServer(userInfo) {
// 实际项目中,这里需要调用后端接口
// 通常还需要结合wx.login获取的code一起发送
wx.login({
success: (loginRes) => {
if (loginRes.code) {
// 调用自己的后端接口,传递code和userInfo
wx.request({
url: 'https://你的后端接口地址',
method: 'POST',
data: {
code: loginRes.code,
userInfo: userInfo
},
success: (res) => {
console.log('用户信息发送成功', res.data)
// 可以在这里处理后端返回的登录状态等信息
},
fail: (err) => {
console.error('用户信息发送失败', err)
wx.showToast({
title: '服务器连接失败',
icon: 'none'
})
}
})
} else {
console.error('获取code失败', loginRes.errMsg)
}
}
})
}
}
}
Page({
getUserInfoHandler(e) {
// 调用 getUserProfile 获取用户信息
wx.getUserProfile({
success: (res) => ·
console.log('用户信息获取成功', res.userInfo)
// 处理用户信息(如保存到本地或发送到后端)
},
fail: (err) => {
console.log('用户拒绝授权', err)
}
})
}
})
4.后端基于SpringBoot、redis实现
处理从小程序前端发送过来的code。该接口应使用code调用微信的jscode2session接口,以换取用户的openId、sessionKey和unionId
//request
public class UserLoginRequest {
private String code;
private String nickname;
private String avatar;
private String phone
public String getCode() { return code; }
public void setCode(String code) { this.code = code; }
//......
}
//reponse
public class WxCode2SessionResponse {
private String openid; // 用户唯一标识
private String session_key; // 会话密钥
private String unionid; // UnionID(多平台统一标识)
private Integer errcode; // 错误码
private String errmsg; // 错误信息
调用微信官方接口换取 openid 和 session_key
@Service
public class WxService {
@Autowired
private WxConfig wxConfig;
@Autowired
private RestTemplate restTemplate; // 用于发送HTTP请求
/**
* 调用微信code2Session接口
* @param code 前端传递的code
* @return 微信返回的结果
*/
public WxCode2SessionResponse getSessionInfo(String code) {
// 1. 获取接口地址
String url = wxConfig.getCode2SessionUrl(code);
// 2. 发送GET请求
String response = restTemplate.getForObject(url, String.class);
// 3. 解析JSON响应
ObjectMapper mapper = new ObjectMapper();
try {
return mapper.readValue(response, WxCode2SessionResponse.class);
} catch (JsonProcessingException e) {
throw new RuntimeException("解析微信接口响应失败", e);
}
}
}
处理用户信息并生成 Token(生产环境进行加密返回)返回给前端
@Service
public class UserService {
@Autowired
private UserMapper userMapper; // 假设已定义的数据库操作接口
@Autowired
private StringRedisTemplate redisTemplate; // 用于存储Token
/**
* 处理登录逻辑:保存用户信息并生成Token
* @param openid 用户唯一标识
* @param userInfo 前端传递的用户信息
* @return 生成的Token
*/
public String handleLogin(String openid, UserLoginRequest userInfo) {
//处理用户信息
//生成自定义登录态Token
String token = UUID.randomUUID().toString().replaceAll("-", "");
//加密()
//存储Token到Redis,设置过期时间(如2小时)
redisTemplate.opsForValue().set(
"login:token:" + token,
openid,
2,
TimeUnit.HOURS
);
return token;
}
}
@RestController
@RequestMapping("/user")
public class LoginController {
@Autowired
private WxService wxService;
@Autowired
private UserService userService;
/**
* 处理微信小程序登录请求
*/
@PostMapping("/login")
public Result login(@RequestBody UserLoginRequest request) {
// 1. 调用微信接口获取openid
WxCode2SessionResponse sessionResponse = wxService.getSessionInfo(request.getCode());
// 2. 检查微信接口返回是否成功
if (sessionResponse.getErrcode() != null && sessionResponse.getErrcode() != 0) {
return Result.fail("微信登录失败:" + sessionResponse.getErrmsg());
}
// 3. 处理用户信息并生成Token
String token = userService.handleLogin(sessionResponse.getOpenid(), request);
// 4. 返回Token给前端
return Result.success("登录成功", token);
}
}
5.注意事项
安全性:确保在传输过程中保护用户的隐私信息,如openId和sessionKey。
调试:在开发过程中,确保使用正确的AppID和AppSecret,并且服务器域名已正确配置在微信的合法域名列表中。
用户体验:提供清晰的授权提示和错误处理机制,以提升用户体验。
更多推荐

所有评论(0)