微信/支付宝网页扫码授权
微信/支付宝网页扫码授权
扫码授权指通过扫描二维码获取微信的openid或支付宝的userId;
流程:扫描二维码(这个一般是自己生成的,因为一般会带一些参数),这个二维码路径为后台服务器的接口 -》 后台收到请求后,配置好参数转发请求给第三方api(微信、支付宝),如果参数配置那些没问题,第三方会通过配置的回调地址回调到相应前端页面(页面前端给,配置的页面路径需要在微信/支付宝上配置,因为有白名单限制),回调是会把code带到页面里面去 -》 通过code请求服务器接口获取微信openid/支付宝userId
注:aliProperties、properties为yml中的配置信息。自己封装。appid、公钥、私钥注意上下一致
生成二维码
/**
* 生成扫码图片
* @return
*/
public static final String BASE64_PREFIX = "data:image/png;base64,";
@GetMapping("createUrl")
public Object createUrl(String orderId){
String url = urlPrefix + "wx/webpage/authorization?orderId=" + orderId;
// base64
String qrcodImg = BASE64_PREFIX + Base64.getEncoder().encodeToString(QrCodeUtil.generatePng(url,250,250));
return ResponseUtil.ok(qrcodImg);
}
授权
转发请求的参数不理解的可以看官方文档:
微信:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0
支付宝:https://opendocs.alipay.com/open/53/104114
/**
* 授权
* @param orderId
* @return
* @throws Exception
*/
@GetMapping("authorization")
public ModelAndView authorization(HttpServletRequest request, String orderId) throws Exception {
logger.info("-------->h5授权:" + JSONObject.toJSONString(orderId));
// todo:业务逻辑
String userAgent = request.getHeader("user-agent");
// h5回调地址;需要配置白名单;需要转码
String userAppAuthUrl = "**********";
String redirectUrl = URLEncoder.encode(userAppAuthUrl, "utf-8");
String redLocation = "";
if (userAgent != null && userAgent.contains("AlipayClient")) {
// 支付宝
redLocation = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?app_id=" + aliProperties.getHsAppId() + "&state=" + orderId + "&scope=auth_base&redirect_uri=" + redirectUrl;
} else if (userAgent != null && userAgent.contains("MicroMessenger")) {
// 微信
redLocation = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + properties.getHsAppId() + "&redirect_uri=" + redirectUrl + "&response_type=code&scope=snsapi_base&state=" + orderId + "#wechat_redirect";
}else{
// 报错的回调地址
redLocation = urlPrefix + "pay/#/pages/pay/error";
}
return new ModelAndView(new RedirectView(redLocation));
}
获取微信用户的openId
/**
* 获取微信用户的openId
* @param code
* @return
*/
@GetMapping("getWxOpenId")
public Object getWxOpenId(String code) {
logger.info("-------->获取微信用户的openId" + JSONObject.toJSONString(code));
String appid = properties.getHsAppId();
String secret = properties.getHsAppSecret();
String url = "https://api.weixin.qq.com/sns/oauth2/access_token"
+ "?appid=AppId"
+ "&secret=AppSecret"
+ "&code=CODE"
+ "&grant_type=authorization_code";
url = url.replace("AppId", appid)
.replace("AppSecret", secret)
.replace("CODE", code);
// 根据地址获取请求
HttpGet request = new HttpGet(url);//这里发送get请求
// 获取当前客户端对象
HttpClient httpClient = HttpClientBuilder.create().build();
// 通过请求对象获取响应对象
Map<String,Object> map = new HashMap<>();
try {
HttpResponse response = httpClient.execute(request);
String jsonStr = EntityUtils.toString(response.getEntity(), "utf-8");
logger.info(jsonStr);
JSONObject jsonTexts = (JSONObject) JSON.parse(jsonStr);
if (jsonTexts.get("openid") == null) {
return ResponseUtil.fail(jsonStr);
}
map.put("accessToken",jsonTexts.get("access_token"));
map.put("expiresIn",jsonTexts.get("expires_in"));
map.put("refreshToken",jsonTexts.get("refresh_token"));
map.put("openid",jsonTexts.get("openid"));
map.put("scope",jsonTexts.get("scope"));
} catch (IOException e) {
e.printStackTrace();
logger.error("获取微信openid异常:" + e.getMessage());
}
return ResponseUtil.ok(map);
}
获取支付宝用户的userId
/**
* 获取支付宝用户的userId
* @param code
* @return
*/
@GetMapping("getAliPayUserId")
public Object getAliPayUserId(String code) {
String userId = "";
String appid = aliProperties.getHsAppId();
String privateKey = aliProperties.getHsRsaPrivateKey();
String publicKey = aliProperties.getHsRsaPublicKey();
String serverUrl = "https://openapi.alipay.com/gateway.do";
AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appid, privateKey, "json", "UTF-8", publicKey, "RSA2");
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode(code);//这个就是第一步获取的auth_code
request.setGrantType("authorization_code");//这个固定值
try {
AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
userId = oauthTokenResponse.getUserId();
} catch (AlipayApiException e) {
logger.error("获取支付宝用户userId异常:" + e.getErrCode() + e.getErrMsg());
}
return ResponseUtil.ok(userId);
}