好的,以下是微信小程序获取 openid
和手机号的前后端完整实现,基于 Spring Boot 和微信小程序的开发框架。
一、微信小程序前端实现
1. 获取 openid
微信小程序通过 wx.login()
获取临时登录凭证(code
),然后将 code
发送到后端,后端通过 code
换取 openid
。
前端代码示例:
// 在小程序的登录页面
wx.login({
success(res) {
if (res.code) {
// 将 code 发送到后端
wx.request({
url: 'https://your-backend-domain.com/minapp/login', // 替换为你的后端接口地址
method: 'POST',
data: {
code: res.code
},
success(res) {
console.log('获取openid成功', res.data);
// 保存 openid 或其他返回的数据
},
fail(err) {
console.error('获取openid失败', err);
}
});
} else {
console.error('登录失败!' + res.errMsg);
}
}
});
2. 获取手机号
微信小程序通过 wx.getPhoneNumber()
获取手机号,但需要用户授权。用户授权后,前端会收到一个加密的手机号信息(encryptedData
和 iv
),需要将这些数据发送到后端进行解密。
前端代码示例:
// 在小程序的页面中
wx.getPhoneNumber({
success(res) {
if (res.encryptedData && res.iv) {
// 将 encryptedData 和 iv 发送到后端
wx.request({
url: 'https://your-backend-domain.com/minapp/getPhoneNumber', // 替换为你的后端接口地址
method: 'POST',
data: {
encryptedData: res.encryptedData,
iv: res.iv
},
success(res) {
console.log('获取手机号成功', res.data);
// 保存手机号或其他返回的数据
},
fail(err) {
console.error('获取手机号失败', err);
}
});
} else {
console.error('获取手机号失败,用户未授权');
}
},
fail(err) {
console.error('获取手机号失败', err);
}
});
二、Spring Boot 后端实现
1. 添加依赖
在 pom.xml
文件中添加以下依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
</dependencies>
2. 配置文件
在 application.yml
文件中配置微信小程序的 appid
和 secret
:
wx:
miniapp:
appid: your_app_id
secret: your_app_secret
3. 后端代码实现
3.1 获取 openid
Controller:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class WechatController {
@Value("${wx.miniapp.appid}")
private String appId;
@Value("${wx.miniapp.secret}")
private String appSecret;
private final RestTemplate restTemplate = new RestTemplate();
@PostMapping("/minapp/login")
public String getOpenId(@RequestBody Map<String, String> request) {
String code = request.get("code");
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId +
"&secret=" + appSecret +
"&js_code=" + code +
"&grant_type=authorization_code";
String response = restTemplate.getForObject(url, String.class);
return response; // 返回 openid 和 session_key 等信息
}
}
3.2 获取手机号
Controller:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import java.security.AlgorithmParameters;
import java.security.spec.IVParameterSpec;
import java.util.Base64;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
@RestController
public class WechatController {
@Value("${wx.miniapp.appid}")
private String appId;
@PostMapping("/minapp/getPhoneNumber")
public String getPhoneNumber(@RequestBody Map<String, String> request) {
String encryptedData = request.get("encryptedData");
String iv = request.get("iv");
String sessionKey = request.get("sessionKey"); // sessionKey 需要从前端传递或从数据库获取
try {
// 解密手机号
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
SecretKeySpec keySpec = new SecretKeySpec(Base64.getDecoder().decode(sessionKey), "AES");
AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
params.init(new IVParameterSpec(Base64.getDecoder().decode(iv)));
cipher.init(Cipher.DECRYPT_MODE, keySpec, params);
byte[] result = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
String phoneNumber = new String(result, "UTF-8");
return phoneNumber; // 返回解密后的手机号
} catch (Exception e) {
e.printStackTrace();
return "解密失败";
}
}
}
三、完整流程说明
- 前端流程:
- 用户点击登录按钮,调用
wx.login()
获取code
。 - 将
code
发送到后端接口/minapp/login
。 - 后端通过
code
换取openid
和session_key
,返回给前端。 - 用户点击获取手机号按钮,调用
wx.getPhoneNumber()
。 - 将返回的
encryptedData
和iv
发送到后端接口/minapp/getPhoneNumber
。 - 后端使用
session_key
解密encryptedData
,获取手机号。
- 用户点击登录按钮,调用
- 后端流程:
- 接收前端发送的
code
,通过微信接口换取openid
和session_key
。 - 接收前端发送的
encryptedData
和iv
,使用session_key
解密,获取手机号。
- 接收前端发送的
四、注意事项
- 安全性:
session_key
是敏感信息,不要直接存储在前端,应存储在服务器端。- 解密手机号的操作应在服务器端完成,避免将
session_key
暴露给前端。
- 微信限制:
- 每个
session_key
有效期为 2 小时,建议在用户登录时重新获取session_key
。
- 每个
- 错误处理:
- 前端和后端都需要处理可能出现的错误,如用户未授权、解密失败等。
通过以上代码和流程,你可以实现微信小程序获取 openid
和手机号的功能。如果有其他问题,欢迎继续提问!