首先贴上官方文档: 网页授权 | 微信开放文档
用户无感知静默授权
首先前端判断是否是在微信内部浏览器内,然后根据自己的业务做判断
// 判断是否为微信浏览器
function isWeixinBrowser() {
let ua = navigator.userAgent.toLowerCase();
return /micromessenger/.test(ua) ? true : false;
}
请求后端获取跳转授权链接
/**
* 获取微信授权CODE链接
* @param timeStamp 这里的参数是结合业务使用的,请根据实际业务做调整
* @return
*/
@GetMapping("/getWechatCode")
public AjaxResult getOpenId(@RequestParam("timeStamp") String timeStamp) throws UnsupportedEncodingException {
// 获取订单信息
String data = redisTemplate.opsForValue().get(timeStamp);
if (ObjectUtils.isNotEmpty(data)) {
JSONObject dataObj = JSONObject.parseObject(data);
BaseTradeOrderInfo orderInfo = JSONObject.parseObject(dataObj.getString("unified"), BaseTradeOrderInfo.class);
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"
+ "appid=" + orderInfo.getWechatParams().getAppid()
+ "&redirect_uri=" + URLEncoder.encode(serverHost + "/wechat/codeCallback", "UTF-8")
+ "&response_type=code"
+ "&scope=snsapi_userinfo"
+ "&state=" + timeStamp // 自定义参数,由于这里时间戳是纯数字所以没有encode的必要,视参数类型而定是否encode
+ "#wechat_redirect";
logger.info("-------->url-------->{}", url);
return AjaxResult.success("请求成功", url);
} else {
return AjaxResult.error("数据已过期");
}
}
前端获取链接后直接跳转
注意!redirect_uri需要在公众号后台添加业务域名,否则跳转后会提示redirect_uri参数错误,但并不是你的参数不对而是没有配置!
公众号后台下载好微信的校验文件后放到服务器上使其能够通过域名直接被访问,比如:浏览器访问 https://baidu.com/微信校验文件.txt 能够显示文本内容的就表示成功。
这里是nginx的访问配置
location ~ ^.+\.txt$ {
root /www/wechatFile/; // 这里是校验文件的目录
}
跳转后会重定向到你填入的redirect_uri参数
接收微信传递的Get参数
/**
* openid回调
* @return
*/
@GetMapping("/codeCallback")
public void callback(@RequestParam("code") String code, @RequestParam("state") String state, HttpServletResponse response) {
// 获取订单信息
String data = redisTemplate.opsForValue().get(state);
if (ObjectUtils.isNotEmpty(data)) {
JSONObject dataObj = JSONObject.parseObject(data);
BaseTradeOrderInfo orderInfo = JSONObject.parseObject(dataObj.getString("order"), BaseTradeOrderInfo.class);
logger.info("订单信息------>{}", BaseTradeOrderInfo);
WechatAccount account = new WechatAccount(); // 保存的微信公众号配置数据
if (ObjectUtils.isEmpty(account)) {
throw new IllegalArgumentException("该商户微信公众号未配置于系统内");
}
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + orderInfo.getWechatParams().getAppid() +
"&secret=" + subAccount.getSubAppSecret() +
"&code=" + code +
"&grant_type=authorization_code";
String result = HttpUtils.sendGet(url, ""); // 发起GET请求换取openid等数据
JSONObject responseJson = JSONObject.parseObject(result);
logger.info("微信公众号响应参数:{}", responseJson);
if (ObjectUtils.isEmpty(responseJson.getString("openid"))) {
throw new IllegalArgumentException(responseJson.toJSONString());
}
String openId = responseJson.getString("openid");
// 获取后完成接下来的业务 如果需要向前端传递openid参数可以将openid放入缓存,重定向前端后前端再查询获取,或者直接携带为url的query参数传递给前端
try {
String redirectUrl = serverHost + "/#/业务地址?业务参数=" + openId;
response.sendRedirect(redirectUrl); // 重定向到前端业务页面
} catch (Exception e) {
e.printStackTrace();
}
}
}
到此就结束了