微信小程序-获取OPENID做为用户的唯一标识
需求-获取openId做为用户的唯一标识
以下内容基于UNI-APP+SPRINGBOOT
1 分析需求
获取openId需要调用调用 auth.code2Session接口(GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code),该接口需要3+1个参数,这里的3是:appid+secret+js_code。
3个参数的获取方法
- js_code需要通过调用 wx.login() 获取临时登录凭证code ,而在小程序插件中使用时,需要在用户信息功能页中获得用户授权之后调用。否则将返回 fail, 这时候如果打印wx.login的返回值res,那么code是“the code is a mock one”。因此,我们还需要先获得授权,然后使用wx.login获得code
- 可以通过下述步骤找到appid,secret。
微信公众平台 > > > 左侧菜单栏- - -开发- - -开发管理 > > > 开发设置
请求参数和返回值详见官网:HTTPS://DEVELOPERS.WEIXIN.QQ.COM/MINIPROGRAM/DEV/API-BACKEND/OPEN-API/LOGIN/AUTH.CODE2SESSION.HTML
为优化用户体验,使用 WX.GETUSERINFO 接口直接弹出授权框的开发方式将逐步不再支持。从2018年4月30日开始,小程序与小游戏的体验版、开发版调用 WX.GETUSERINFO 接口,将无法弹出授权询问框,默认调用失败。正式版暂不受影响。开发者可使用以下方式获取或展示用户信息
2 解决思路
- 获得授权
- 通过WX.LOGIN()获得CODE
- 在微信开发平台获取APPID,SECRET
- 调用AUTH.CODE2SESSION(GET HTTPS://API.WEIXIN.QQ.COM/SNS/JSCODE2SESSION?APPID=APPID&SECRET=SECRET&JS_CODE=JSCODE&GRANT_TYPE=AUTHORIZATION_CODE)接口获得OPENID,
3 获得授权
调用WX.GETUSERPROFILE可弹出确认授权框,建议事件驱动
代码示例如下:
getUserInfo:function(){
wx.getUserProfile({
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success: (res) => {
console.log(res);
console.log(res.userInfo);
// 获取code
this.getCode();
},
fail: (res)=>{
console.log(res)
}
})
},
4 获得code
getCode(){
let _this = this;
wx.login({
success (res) {
console.log(res);
let code=res.code;
if (code) {
//发起网络请求,_this.request是我基于wx.request做的封装,后附着代码
_this.request({
// url 自己的服务器或者后端的请求路径
url: 'http://localhost:8010/weixin/login',
data: {code:code}
}).then(res => {
console.log(res);
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
}
这里我是封装的WX.REQUEST,路径SRC/UTILS/REQUEST.JS,
export default (params) => {
return new Promise((resolve, reject) => {
// 加载中
uni.showLoading({
title: "加载中"
})
wx.request({
...params,
success(res) {
resolve(res.data);
},
fail(err) {
reject(err);
},
complete() {
uni.hideLoading();
}
})
})
}
在MAIN.JS中全局引入REQUEST,
import request from "./utils/request";
Vue.prototype.request = request;
5 后端接收code,返回openId
后端通过CODE向HTTPS://API.WEIXIN.QQ.COM/SNS/JSCODE2SESSION?APPID=APPID&SECRET=SECRET&JS_CODE=JSCODE&GRANT_TYPE=AUTHORIZATION_CODE发送请求,获得OPENID,并返回
后端参考原文:https://blog.csdn.net/mengdi_cao/article/details/109717187
5.1 封装请求参数
@Getter
public class WeixinLoginParams {
private String secret="b1d3de815c086fcc88f0fe06d4dc7da9";
private String appid = "wx753dc3d18bcd580e";
private final String grantType="authorization_code";
}
5.2 封装返回值
@Data
@ToString
public class WXloginRes {
private String openid;
private String sessionKey;
private String errcode;
private String errmsg;
}
5.3 封装工具类用于向接口发起请求
import com.alibaba.fastjson.JSONObject;
import com.restaurant.order.vo.WXloginRes;
import com.restaurant.order.vo.WeixinLoginParams;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
public class WeiXinLoginUtils {
public static WXloginRes getLoginResult(String code){
RestTemplate restTemplate = new RestTemplate();
WeixinLoginParams loginParams = new WeixinLoginParams();
WXloginRes wXloginRes = new WXloginRes();
// 封装请求参数
String url = "https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type={grantType}";
Map<String, String> requestMap = new HashMap<>();
requestMap.put("appid", loginParams.getAppid());
requestMap.put("secret", loginParams.getSecret());
requestMap.put("grantType", loginParams.getGrantType());
requestMap.put("code", code);
// 发送请求,获得返回值
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class,requestMap);
// 转换成json对象
JSONObject jsonObject=JSONObject.parseObject(responseEntity.getBody());
String openId=jsonObject.getString("openid");
String sessionKey=jsonObject.getString("session_key");
String errcode = jsonObject.getString("errcode");
String errmsg = jsonObject.getString("errmsg");
// 给返回对象wXloginRes赋值
wXloginRes.setOpenid(openId);
wXloginRes.setOpenid(sessionKey);
wXloginRes.setErrcode(errcode);
wXloginRes.setErrmsg(errmsg);
return wXloginRes;
}
}
5.4 书写接口
这里的Result是我自己封装的统一返回对象,详见:https://blog.csdn.net/qq_43644923/article/details/116507939?spm=1001.2014.3001.5501
@GetMapping("/login")
public Result login(String code){
if (code==null){
return Result.error("错误,请重新授权");
}else {
return Result.success(WeiXinLoginUtils.getLoginResult(code));
}
}
d);
wXloginRes.setOpenid(sessionKey);
wXloginRes.setErrcode(errcode);
wXloginRes.setErrmsg(errmsg);
return wXloginRes;
}
}
##### 4.5.4 书写接口
这里的Result是我自己封装的统一返回对象,详见:https://blog.csdn.net/qq_43644923/article/details/116507939?spm=1001.2014.3001.5501
```java
@GetMapping("/login")
public Result login(String code){
if (code==null){
return Result.error("错误,请重新授权");
}else {
return Result.success(WeiXinLoginUtils.getLoginResult(code));
}
}
http://www.jnnr.cn/news_show_409.html