写一个微信的第三方登录(网页版的)功能,移动端的是授权,请注意两者的区别,观看了好多文档和官方的开发文档。终于把这个功能给实现了,下面是代码以及流程。
一、首先我们需要在微信开放平台申请一个网站应用
注意这个是收费的(别想了,微信的接口想白嫖是不可能的)
申请完之后会有appid和密钥 要保存好 后面会有需要,之后要配置我们的回调域(这个是字符串 不要加上http||https协议)配置完成之后,就可以就行开发了 (对于初学者来说可以去申请一个测试号就行测试 申请链接:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 进行测试 )
前端的代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>微信登录</title>
</head>
<body>
<div onclick="dianji()">微信登录</div>
<div id="login_container">
</div>
</body>
//实现二维码 就要引入这个js样式,如果是上线的话,需要把这个js下载下来引入
<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>
//jquery文件引入
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</html>
js的代码:
function dianji() {
var obj = new WxLogin({
self_redirect:true,
id:"login_container", //要与你在那里生成二维码的div id 一致
appid: "appid", //你申请的appid
scope:"snsapi_login,snsapi_userinfo",//你的权限
redirect_uri:encodeURIComponent("你自己配置的回调地址"),//url要进行encodeURIComponent编码
state: "STATE",//微信官方接口为了防止跨域攻击要加的参数 可以自己定义
style: "black",//样式
href: ""//可以引入你自己的样式 注意这个只能是网络中的
});
}
后端的代码:
public class WxLoginController{
@Autowired
private WxLoginService wxLoginService;
@RequestMapping(value = "/MessageController/get_weiXingInformation", method=RequestMethod.GET)
@ResponseBody
public String wxLogin(@RequestParam("code") String code,@RequestParam("wzid") Integer wzid,@RequestParam("mid") Integer mid,@RequestParam("wzUrl") String wzUrl,@RequestParam("stafftoken") String stafftoken,HttpServletResponse res) throws IOException{
if (code==null) {
return ResultJsonData.resultFailed("请扫码");
}
if (wzid==null||wzUrl==null||mid==null||stafftoken==null) {
return ResultJsonData.resultFailed("请查看参数: id="+wzid+", 分享者id="+mid+", 文章唯一标识id参数="+stafftoken);
}
//向第三方微信发送的url
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=appid&secret=密钥&code="+code+"&grant_type=authorization_code";
JSONObject jsonObject = this.httpGet(url);//向第三方发送请求
String accesstoken = jsonObject.getString("access_token"); // 获取微信开放平台票据号
String refreshtoken = jsonObject.getString("refresh_token");//获取微信开放平台的刷新token
String openId = jsonObject.getString("openid"); // 获取登录微信的唯一凭证号
url="https://api.weixin.qq.com/sns/userinfo?access_token="+accesstoken+"&openid="+openId; // 该url用于从微信那里获取用户数据
jsonObject = this.httpGet(url);//向第三方发送请求
Visitor visitor = new Visitor(); //创建微信用户对象 用于存储
//根据key获取jsonObject对象并转换为String类型并存储到Visitor对象中 主要用于添加wx用户
visitor.setOpenid(jsonObject.getString("openid").toString());//用户的标识
visitor.setNickname(jsonObject.getString("nickname").toString());//用户名称
visitor.setSex(jsonObject.getString("sex").toString());//用户性别
visitor.setProvince(jsonObject.getString("province").toString());//用户省份
visitor.setCity(jsonObject.getString("city").toString());//用户城市
visitor.setCountry(jsonObject.getString("country").toString());//用户国家
visitor.setHeadimgurl(jsonObject.getString("headimgurl").toString());//用户头像
visitor.setPrivilege(jsonObject.getString("privilege").toString());//用户特权信息
visitor.setUnionid(jsonObject.getString("unionid").toString());//用户唯一身份
visitor.setAccesstoken(accesstoken);//用户交换的token
visitor.setRefreshtoken(refreshtoken);//用来刷新token的凭证
Visitor wxUser = wxLoginService.getWxUser(visitor.getUnionid());//向数据查询是否有这个微信用户
if (null!=wxUser) {
//查询到了有这个用户 但是依然要更新信息 unionid 是不变的
int add = wxLoginService.updateWxUserByUnionid(wxUser);
if (add>0) {
System.out.println("有这个用户"+wzUrl+"&unionid="+wxUser.getUnionid()+"&stafftoken="+stafftoken);
//重定向我的原Url 并携带参数 unionid 是微信的唯一ID wzid 是文章的D stafftoken 是文章的标识
res.sendRedirect(wzUrl+"&unionid="+wxUser.getUnionid()+"&stafftoken="+stafftoken+"&id="+wzid);
return ResultJsonData.resultFailed("wx用户修改成功");
}else {
System.out.println(wzUrl+"&unionid="+wxUser.getUnionid()+"&stafftoken="+stafftoken+"&id="+wzid);
//重定向我的原Url 并携带参数 stafftoken 是文章的标识
res.sendRedirect("有这个用户失败"+wzUrl);
return ResultJsonData.resultFailed("wx用户修改失败");
}
}else {
//没有查询到这个用户 向数据库里添加一个微信用户
int addWxUser = wxLoginService.addWxUser(visitor);
if (addWxUser>0) {
System.out.println("成功加入用户"+wzUrl+"&unionid="+wxUser.getUnionid()+"&stafftoken="+stafftoken);
//重定向我的原Url 并携带参数 unionid 是微信的唯一ID wzid 是文章的ID stafftoken 是文章的标识
res.sendRedirect(wzUrl+"&unionid="+wxUser.getUnionid()+"&stafftoken="+stafftoken+"&wzid="+wzid);
return ResultJsonData.resultFailed("wx用户添加成功");
}else {
System.out.println("加入用户失败"+wzUrl+"&unionid="+wxUser.getUnionid()+"&stafftoken="+stafftoken);
//重定向我的原Url 并携带参数 stafftoken 是文章的标识
res.sendRedirect(wzUrl);
return ResultJsonData.resultFailed("wx用户添加失败");
}
}
}
}
微信授权
==微信授权的解释: 相对于企业开发来说 我们需要申请到公众号或者订阅号(最好是公众号) appid和secret是我们需要的 如果你在微信开放平台上面开发过网站应用 你就要将我们申请到公众号绑定到我们的网站应用里面 这个代表的是 不管你是在我那个应用下 使用的微信登录和授权 你的微信unionid都是唯一的 代表的是同一个人 不需要添加到用户表里面 如果你没有绑定 则微信第三方是不会返回给你unionid的 unionid 这个字段代表的是 对与开发者而言这个字段每个人都是唯一的 (简单点来说就是 微信公众号 和 一个网站应用或者多个网站应用都是我们自己的 那么就是说你用过我的一个网站应用,那么你在我其他的网站应用和公众号里面 你的unionid是唯一的 就是告诉我名下的其他应用 这个人有账号,不用注册了) ==
相关解释 可以去看一下官方文档:微信公众平台
授权前端代码:我们只需要向我们微信第三方的地址跳转就可以 需要用到我们申请到的appid
第一步:用户同意授权,获取code
window.location.href=https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
即可弹出授权页面 选择允许 会向微信第三方发送请求,经过验证你的参数没有问题 微信第三方会跳转到我们设置的回调地址并携带上code参数我们通过
第二步:通过code换取网页授权access_token
通过java向微信第三方发送请求 url地址:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数列表:
参数字段 | 参数说明 |
---|---|
appid | 你申请的appid |
secret | 你申请的密钥 |
grant_type | 必须是authorization_code |
code | 微信向回调地址跳转时携带的参数 |
返回参数:
参数 | 描述 |
---|---|
access_token | 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 |
expires_in | access_token接口调用凭证超时时间,单位(秒) |
refresh_token | 用户刷新access_token |
openid | 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID |
scope | 用户授权的作用域,使用逗号(,)分隔 |
第三步:拉取用户信息(需scope为 snsapi_userinfo)
通过java向微信第三方发送请求 url地址:https://api.weixin.qq.com/sns/userinfo?access_token=你获得的access_token&openid=你获取到的openid&lang=要返回的国家地区语言版本 (中国简体 zh_CN 简体,zh_TW 繁体,en 英语)
返回参数:
参数 | 描述 |
---|---|
openid | 用户的唯一标识 |
nickname | 用户昵称 |
sex | 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 |
province | 用户个人资料填写的省份 |
city | 普通用户个人资料填写的城市 |
country | 国家,如中国为CN |
headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。 |
privilege | 用户特权信息,json 数组,如微信沃卡用户为(chinaunicom) |
unionid | 只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。 |