需求-获取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