引言
实现微信扫码登录关键之处就是获取到微信用户信息,那么这就涉及到了微信授权,通过微信授权我们可以获取到用户信息;微信官方文档写的还是比较详细的,但是没有代码演示,这里我就用代码演示一下如何实现微信授权登录;
可以先看看文档:网页授权
流程梳理
文档中把整个授权流程分为以下几步:
总结来说就是需要通过这几部操作获取一些参数从而通过参数进而获取一些其他信息;
其实我感觉就第一步可能不好理解些,因为参数比较多,调用接口为:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
这里主要注意的就是 redirect_uri 和 scope 两个参数;
scope 文档有解释,就是获取信息的内容和方式的区别,挺好理解的;
而redirect_uri 是该授权接口调用后要重定向的链接,该链接是需要自己实现的,其实就是实现一个重定向的接口,并且重定向后该接口会携带两个参数:code和state:
这个code就是第一步需要获取的主要参数;
剩下的步骤就是继续向下调用接口就好了,就不是特别难理解了;
代码实现
在实现代码前还是需要一些准备工作,准备工作看我的这篇文章:微信公众号扫码登录(一)—— 获取微信公众号二维码这几块部分:
当一切都配置好后,就可以开始具体代码开发了;
其实代码并不难,就是实现两个接口:
第一个接口(/redirect)代码:
// 调用微信授权接口重定向
@GetMapping("/redirect")
public String toRedirectUrl(HttpServletResponse response) {
String redirectUrl = "https://open.weixin.qq.com/connect/oauth2/authorize" +
"?appid=" + WXConstant.APP_ID +
"&redirect_uri=" + WXConstant.REDIRECT_URL +
"&response_type=code" + "&scope=snsapi_userinfo" +
"&state=STATE" + "&connect_redirect=1#wechat_redirect";
try {
response.sendRedirect(redirectUrl); // 重定向url
} catch (IOException e) {
log.error("获取微信code失败: " + e.getMessage());
}
return "重定向成功";
}
这里还是说一下redirect_uri,该重定向url需要重定向到**/redirect/info接口**,所以我的WXConstant.REDIRECT_URL实际是:
http://内网穿透域名/api/wx/redirect/info
那么当我调用/redirect接口时,该接口内部逻辑就是重定向url,然后重定向到/redirect/info接口,此时该接口对应url上就会携带有code和state参数,可以通过微信开发者工具看一下:
调用该接口:
因为scope参数为userinfo,所以需要用户同意授权才行;
点击同意,可以观察network内的请求:
可以看到成功重定向到了/redirect/info接口,并且附带了code和state参数;
到这里文档的第一步就完成了,下面几步就不难了;
第二个接口就是重定向到的/redirect/info接口,下面是代码实现:
// 授权接口重定向回调方法
@GetMapping("/redirect/info")
public BaseResponse<String> redirectInfo(@RequestParam(value = "code") String code,
@RequestParam(value = "state", required = false) String state,
HttpServletResponse response) {
String username = ""; // 微信用户名
try {
// 第二步:通过code获取access_token和openid
String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" +
"?appid=" + WXConstant.APP_ID +
"&secret=" + WXConstant.APP_SECRET +
"&code=" + code +
"&grant_type=authorization_code";
String accessTokenRes = HttpClientUtil.doGet(getAccessTokenUrl);
log.info("accessTokenRes=>" + accessTokenRes);
String accessToken = (String) JSON.parseObject(accessTokenRes).get("access_token");
String openid = (String) JSON.parseObject(accessTokenRes).get("openid");
// 第四步:通过access_token和openid获取到用户信息
String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=" + accessToken +
"&openid=" + openid +
"&lang=zh_CN";
String userInfoRes = HttpClientUtil.doGet(getUserInfoUrl);
WxUserInfo userInfo = JSON.parseObject(userInfoRes, WxUserInfo.class); // 获取到了微信用户信息
username = userInfo.getNickname(); // 获取微信用户名
// TODO 微信用户注册并登录逻辑
log.info("注册成功");
} catch (Exception e) {
e.printStackTrace();
}
return ResultUtils.success(" 用户:" + username + "登录成功!");
}
首先就是该接口会携带有code和state参数,所以就得接收一下code和state;
文档中第三步并不是必须,可以根据实际自行调用;
该接口实际就是调用文档中的第二步和第四步微信提供的接口;
第四步调用就可以获取到用户信息了,主要有以下信息:
也是文档中的,这些看文档就行;
测试一下,授权完成后,重定向到该接口:
可以看到获取到我的微信名,当然也可以获取其他参数,这里就不演示了;
到这里这个接口也就完成了,其实这个接口调用并不难,细心看文档都能实现;
下面是上面代码用到的一些类:
HttpClientUtil在微信公众号扫码登录(一)—— 获取微信公众号二维码一文中有,太长了,这里就不占位了;
然后是WxUserInfo封装类返回用户的一些信息
import lombok.Data;
/**
* 微信用户信息实体
*/
@Data
public class WxUserInfo {
private String openid;
private String nickname;
private Integer sex;
private String language;
private String city;
private String province;
private String country;
private String headimgurl;
}
总结
这就是我们经常用到的微信授权,其实看文档并不是特别难,希望本文对你有帮助,也欢迎各位交流!
这里再多提一嘴,我在实现微信扫码登录时感觉接口调用并不难,但是稍微感觉有点困难的就是如何让用户主动调用到授权接口;我没有找到太好的方法,于是就在公众号界面加了一个登录链接,让用户主动点击从而调用授权接口;
还有一点是用户授权并获取信息是发生在后端的,那么如何把授权成功从而获取到的用户信息通知给前端呢?我看牛客网和微信网易版的微信登录好像在扫码前一直向后端发送请求,应该是获取登录信息;但是我对这一块并不是特别了解,所以我选择了另一种方法,就是通过websocket向前端发送授权登录后的信息,这样也实现了这一功能,但是并不确定这样做到底好不好,所以代码也就不放出来了,如果各位有更好的方法,希望指点一二;