近期,开发一个项目要求PC网站可以进行扫码登陆。
1.前期工作
需要先在微信开放平台进行注册(https://open.weixin.qq.com/),并认证一个网站应用。
点击查看按钮,我们需要记录一下AppID,AppSercret的值,尤其第一次登陆的话生成好的AppSercret值一定要保存好。
这个接口主要用来就是登陆的,我们可以看到他的作用文档写的很详细,只是用来登陆的,不能作为他用,比如我这个项目还需要页面微信扫码支付的操作,只是开通一个这个应用是不够的,我们需要开通其他的带有支付的功能的应用连接商户平台才可以使用微信支付,我的做法是申请了一个服务号,绑定商户平台开通了微信支付功能,这里先不讲解,后期会写到微信支付。
这里面主需要记录AppID,AppSercret ,其中设置的地方就是授权回调域,不需要带www等 直接域名即可
2.开发阶段
2.1 参数配置
这些都是通用的大家直接拿去用 参数直接可以配置在application.properties 中 方便我们直接调用
weixin.pc.fw.accessTokenUrl=https://api.weixin.qq.com/sns/oauth2/access_token?
weixin.pc.fw.userInfoUrl=https://api.weixin.qq.com/sns/userinfo?
这两个就是上面让大家记住的两个参数
weixin.pc.fw.appID=111111111111
weixin.pc.fw.appsecret=11111111111111
2.2 连接地址
根据文档要求正常写就行
AAA就是让大家记住的那个参数
BBB就是回调地址,一定是跟我之前让大家在开放平台设置的回调域名下的地址
2.3后端代码实现
getPcWXAccessToken getPcWeiXinUserInfo 这两个方法可以直接用
pcLoginByWeiXin 这个方法由于里面有我得业务逻辑,我直接删吧删吧就扔上来了,大家直接调试下就可以了,放心可用。
@Value("${weixin.pc.fw.accessTokenUrl}")
private String pcAccessTokenUrl;
@Value("${weixin.pc.fw.userInfoUrl}")
private String pcUserInfoUrl;
@RequestMapping(value = "/pcLoginByWeiXin", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.OK)
public SourceDataBean<UserLoginBean> pcLoginByWeiXin(@RequestBody WeiXinLoginBean bean) {
logger.info("WeiXinLoginController ==> pcLoginByWeiXin(){} code: " + bean.getCode());
SourceDataBean<UserLoginBean> sdb = new SourceDataBean<UserLoginBean>();
UserLoginBean userLoginBean = new UserLoginBean();
String loginName = bean.getLoginName();
String openId = bean.getOpenId();
String code = bean.getCode(); // 微信code
/** 错误信息 **/
if (StringUtils.isBlank(userId) && StringUtils.isBlank(code) && loginName == null) {
sdb.setMessage("501", "微信code为空");
return sdb;
}
if (openId == null && code != null) {
// 第一次进入界面,code不空,openid为空,根据code获取openid,然后查询是否存在用户信息。
Map<String, String> accessTokenMap = getPcWXAccessToken(code); // 获取getWXAccessToken(微信网站PC扫码登录)
/** 请求微信服务器错误 **/
if (accessTokenMap.get("errcode") != null) {
logger.error("LoginController ==> newLoginByWeiXin.getWXAccessToken(){errcode:"
+ accessTokenMap.get("errcode") + ",errmsg:" + accessTokenMap.get("errmsg") + "}");
sdb.setMessage(accessTokenMap.get("errcode"), accessTokenMap.get("errmsg"));
return sdb;
}
openId = accessTokenMap.get("openid");
accessToken = accessTokenMap.get("access_token");
unionid = accessTokenMap.get("unionid");
// 查询出微信信息
Map<String, String> wxUserMap = this.getPcWeiXinUserInfo(openId, accessToken); // 获得微信用户信息
/** 获取微信信息异常 **/
if (wxUserMap.get("errcode") != null) {
logger.error("LoginController ==> loginByWeiXin.getWeiXinUserInfo(){errcode:" + wxUserMap.get("errcode")
+ ",errmsg:" + wxUserMap.get("errmsg") + "}");
sdb.setMessage(wxUserMap.get("errcode"), wxUserMap.get("errmsg"));
return sdb;
}
}
return sdb;
}
/**
* 获取getPcWXAccessToken(微信网站PC扫码)
*
*/
private Map<String, String> getPcWXAccessToken(String code) {
logger.info("WeiXinLoginController ==> getPcWXAccessToken(){}");
Map<String, String> resMap = new HashMap<String, String>();
StringBuffer target = new StringBuffer();
target.append(pcAccessTokenUrl).append("appid=").append(pcAppID).append("&secret=").append(pcAppsecret)
.append("&code=").append(code).append("&grant_type=authorization_code");
logger.info("WeiXinLoginController ==> getPcWXAccessToken(){} target: " + target);
ClientResponseEntity responceEntity = HttpClientUtil.getMethod(target.toString(), "zh-cn");
String resMessageString = responceEntity.getMessage();
logger.info("WeiXinLoginController ==> getPcWXAccessToken(){} resMessageString: " + resMessageString);
JSONObject jSONObject = JSON.parseObject(resMessageString);
if (jSONObject != null && jSONObject.get("errcode") != null) { // 有错误码
String errcode = String.valueOf(jSONObject.get("errcode"));
String errmsg = String.valueOf(jSONObject.get("errmsg"));
resMap.put("errmsg", errmsg);
resMap.put("errcode", errcode);
} else {
String accessToken = String.valueOf(jSONObject.get("access_token"));
String refreshToken = String.valueOf(jSONObject.get("refresh_token"));
String openid = String.valueOf(jSONObject.get("openid"));
String expiresIn = String.valueOf(jSONObject.get("expires_in"));
String unionid = String.valueOf(jSONObject.get("unionid"));
resMap.put("access_token", accessToken);
resMap.put("refresh_token", refreshToken);
resMap.put("openid", openid);
resMap.put("expires_in", expiresIn);
resMap.put("unionid", unionid);
}
return resMap;
}
/**
* 获得微信用户信息(微信网站PC扫码)
*
* @param openId
* @param accessToken
* @return
*/
private Map<String, String> getPcWeiXinUserInfo(String openId, String accessToken) {
Map<String, String> resMap = new HashMap<String, String>();
StringBuffer url = new StringBuffer(pcUserInfoUrl);
url.append("access_token=").append(accessToken).append("&").append("openid=").append(openId).append("&")
.append("lang=zh_CN");
logger.info("WeiXinLoginController ==> getPcWeiXinUserInfo(){} url: " + url);
ClientResponseEntity responceEntity = HttpClientUtil.getMethod(url.toString(), "zh_CN");
String resMessageString = null;
try {
resMessageString = new String(responceEntity.getMessage().getBytes("ISO-8859-1"), "UTF-8");
// resMessageString =new
// String(responceEntity.getMessage().getBytes(),"utf-8");
} catch (UnsupportedEncodingException e) {
logger.error("WeiXinLoginController ==> getPcWeiXinUserInfo().UnsupportedEncodingException{} 获取用户信息编码错误");
}
logger.info("WeiXinLoginController ==> getPcWeiXinUserInfo(){} resMessageString: " + resMessageString);
JSONObject jSONObject = JSON.parseObject(resMessageString);
if (jSONObject != null && jSONObject.get("errcode") != null) {
String errcode = String.valueOf(jSONObject.get("errcode"));
String errmsg = String.valueOf(jSONObject.get("errmsg"));
resMap.put("errmsg", errmsg);
resMap.put("errcode", errcode);
} else {
String nickname = String.valueOf(jSONObject.get("nickname"));
String openid = String.valueOf(jSONObject.get("openid"));
String sex = String.valueOf(jSONObject.get("sex"));
String province = String.valueOf(jSONObject.get("province"));
String city = String.valueOf(jSONObject.get("city"));
String country = String.valueOf(jSONObject.get("country"));
String headimgurl = String.valueOf(jSONObject.get("headimgurl"));
String unionid = String.valueOf(jSONObject.get("unionid"));
resMap.put("nickname", nickname);
resMap.put("openid", openid);
resMap.put("sex", sex);
resMap.put("province", province);
resMap.put("city", city);
resMap.put("country", country);
resMap.put("headimgurl", headimgurl);
resMap.put("unionid", unionid);
}
return resMap;
}
2.4调试的时候前端JS的写法
var openId = localStorage.getItem('openId');
$(document).ready(function () {
var user = localStorage.getItem('user');
var code = getUrlParam('code');
alert(code);
if(code!=null){
alert(commonIP + "api/weixinlogin/pcLoginByWeiXin");
$.ajax({
type: "POST",
url: commonIP + "api/weixinlogin/pcLoginByWeiXin",
data: JSON.stringify({
"code":code
}) ,
contentType: 'application/json',
success: function(data) {
if (data.errcode == 200) {
openId = data.openId;
for (var i=0;i<data.dataSource.total;i++) {
if(data.dataSource.list[i] != null
&& data.dataSource.list[i].user!=null
&& data.dataSource.list[i].user.id != null){
$('#farm_username').append('<option style="text-align:center;" value='+data.dataSource.list[i].user.id+'>'+
data.dataSource.list[i].user.farmName+':'+data.dataSource.list[i].user.name+'</option>')
}
}
} else {
if(data.errcode == '400'){
openId = data.openId;
window.top.location.href = 'login.html?openId='+openId;
}else if(data.errcode == '40029'){
alert('无效的微信code');
}
}
}
});
}else if(user != null){
$('#farm_username').append('<option value='+JSON.parse(user).id+'>'+
JSON.parse(user).farmName+':'+JSON.parse(user).name+'</option>')
}
});
这样我们PC端微信扫码登陆的功能就完成了
3.效果