上面是官网发布的时序图:(前提是给第三方已经通过了微信的授权)
1、用户对第三方说:我要用微信方式登录你们
2、第三方对微信说:用户要用微信登录我们,我需要这个用户的数据
3、微信问用户:有个第三方要你数据,给不给。用户说给
4、微信对第三方说:用户同意了,你拿着临时证明来取吧
5、第三方带着临时证明和授权时候的信息取用户信息
6、微信核对以上信息后把用户信息交给第三方
第一步:
前端:
1、在页面中先引入如下JS文件(支持https):http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js
2、在需要使用微信登录的地方实例以下JS对象:
var obj = new WxLogin({
self_redirect:true,
id:"login_container",
appid: "",
scope: "",
redirect_uri: "",
state: "",
style: "",
href: ""
});
参数 | 说明 |
---|---|
id | 页面显示二维码的容器id |
appid | 申请通过的appid |
scope | 应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可 |
redirect_uri | 重定向地址 |
前端整体代码:
mounted() {
// 注册全局登录事件对象
window.loginEvent = new Vue();
// 监听登录事件
loginEvent.$on("loginDialogEvent", function () {
document.getElementById("loginDialog").click();
});
// 触发事件,显示登录层:loginEvent.$emit('loginDialogEvent') //初始化微信js
const script = document.createElement("script");
script.type = "text/javascript";
script.src =
"https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js";
document.body.appendChild(script);
// 微信登录回调处理
let self = this;
window["loginCallback"] = (name, token, openid,phone) => {
self.loginCallback(name, token, openid,phone);
};
},
methods: {
weixinLogin() {
this.dialogAtrr.showLoginType = "weixin";
weixinApi.getLoginParam().then((response) => {//调用后端方法封装数据
var obj = new WxLogin({
self_redirect: true,
id: "weixinLogin", // 需要显示的容器id
appid: response.data.appid, // 公众号appid wx*******
scope: response.data.scope, // 网页默认即可
redirect_uri: response.data.redirectUri, // 授权成功后回调的url
state: response.data.state, // 可设置为简单的随机数加session用来校验
style: "black", // 提供"black"、"white"可选。二维码的样式
href: "", // 外部css文件url,需要https
});
}).catch(()=>{
console.log("出错了")
});
},
}
后端方法:
try {
String redirectUri = URLEncoder.encode(ConstantPropertiesUtil.WX_OPEN_REDIRECT_URL, "UTF-8");
Map<String, Object> map = new HashMap<>();
map.put("appid", ConstantPropertiesUtil.WX_OPEN_APP_ID);
map.put("scope", "snsapi_login");
map.put("redirectUri", redirectUri);
map.put("state", System.currentTimeMillis() + "王木风");//该参数可用于防止csrf攻击(跨站请求伪造攻击),非必须携带
return R.ok().data(map);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
第二步:
请求:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数 | 说明 |
---|---|
secret | 应用密钥AppSecret,申请通过后获得 |
appid | 申请通过的appid |
code | 上一步获取的 |
grant_type | 填authorization_code(固定的) |
后端被回调方法:
StringBuffer baseAccessTokenUrl = new StringBuffer().append("https://api.weixin.qq.com/sns/oauth2/access_token")
.append("?appid=%s")
.append("&secret=%s")
.append("&code=%s")
.append("&grant_type=authorization_code");
String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
ConstantPropertiesUtil.WX_OPEN_APP_ID,//appid
ConstantPropertiesUtil.WX_OPEN_APP_SECRET,//secret密钥
code);
// 2.2使用工具发送请求
String accesstokenInfo = HttpClientUtils.get(accessTokenUrl);
返回的accesstokenInfo(JSON串):
参数 | 说明 |
---|---|
access_token | 接口调用凭证 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 授权用户唯一标识 |
scope | 用户授权的作用域,使用逗号(,)分隔 |
unionid | 当且仅当该网站应用已获得该用户的userinfo授权时,才会出现该字段。 |
第三步:通过access_token调用接口(根据openid访问微信获取用户信息)
String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
"?access_token=%s" +
"&openid=%s";
String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);
String resultInfo = HttpClientUtils.get(userInfoUrl);