微信扫码登录步骤
第一步: 生成登录二维码链接的请求接口,比如,链接中appid、redirect_url、scope、state参数需要填充
@ApiOperation(value = "web端微信扫码登录")
@PostMapping("/webWxlogin")
@IgnoreAuth
public ResponseInfo webWxlogin() {
String oauthUrl ="https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
String redirect_uri = null;
try {
redirect_uri = URLEncoder.encode(resourceConfig.getUserUrl() + NotifyConfig.WEB_WX_LOGIN, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String state = MD5Util.md5(DateUtil.format(new Date(), "yyyy-MM-dd"));
oauthUrl = oauthUrl.replace("APPID", ConfigConstant.WEB_WX_APPID).replace("REDIRECT_URI", redirect_uri).replace("SCOPE", "snsapi_login").replace("STATE", state);
return ResponseInfo.success(oauthUrl);
}
第二步:根据第一步生成的链接图片,用户扫码后会跳转到redirect_url请求上,所以我们还需要写个回调的接口,比如
@ApiOperation(value = "web微信登录回调")
@GetMapping("/webWxLoginCallback")
@IgnoreAuth
public ResponseInfo webWxLoginCallback(String code, String state) {
// 1.通过code获取access_token
String url ="https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
url = url.replace("APPID", ConfigConstant.WEB_WX_APPID).replace("SECRET", ConfigConstant.WEB_WX_APPSECRET).replace("CODE", code);
String result = HttpUtil.get(url);
JSONObject tokenObject = JSON.parseObject(result);
log.info("tokenObject:{}", tokenObject);
// 2.通过access_token和openid获取用户信息
String userUrl ="https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
userUrl = userUrl.replace("ACCESS_TOKEN", tokenObject.getString("access_token")).replace("OPENID", tokenObject.getString("openid"));
result = HttpUtil.get(userUrl);
JSONObject userObject = JSON.parseObject(result);
log.info("userObject:{}", userObject);
return loginService.webWxLogin(userObject);
}
第三步:根据第二步接口可以从微信服务器可以获取到用户的相关信息后,可以跳转到真正的登录业务上,比如如下,此处业务涉及到第一次扫码登录会,系统用户表会没有用户的手机号信息,会返回前端相关的提示信息,需要前端跳转到填写手机号信息的页面,所以我们还需要写个处理用户完善信息后提交的接口
/**
* web端微信扫码登录
*/
public ResponseInfo webWxLogin(JSONObject userObject) {
User user = userService.getByUnionid(userObject.getString("unionid"));
if (user == null || user.getMobile() == null) {
Map<String, Object> map = new HashMap<>();
map.put("unionid", userObject.getString("unionid"));
map.put("openid", userObject.getString("openid"));
map.put("nickname", userObject.getString("nickname"));
map.put("headimgurl", userObject.getString("headimgurl"));
return ResponseInfo.error(ResponseEnum.GET_PHONE.getCode(), ResponseEnum.GET_PHONE.getMsg(), map);
}
user.setOpenid(userObject.getString("openid"));
user.setLastLoginTime(LocalDateTime.now());
userService.updateById(user);
if (user.getState() != null && user.getState() == 1 ) {
return ResponseInfo.error(ResponseEnum.ACCOUNT_DISABLED.getCode(), ResponseEnum.ACCOUNT_DISABLED.getMsg());
}
String key = String.valueOf(user.getId()).concat("e");
String token = key.concat(TokenUtil.generateToken());
user.setToken(token);
user.setExpireTime(LocalDateTime.now().plusDays(30));
userService.updateById(user);
Set<String> set = redisUtil.getKeys(RedisConstant.TOKEN_USER.concat(key).concat("*"));
redisUtil.delete(set);
redisUtil.set(RedisConstant.TOKEN_USER.concat(token), user.getId(), RedisConstant.DEFAULT_EXPIRE);
return ResponseInfo.success(token);
}
第四步: 处理用户绑定手机号的请求接口,如下
@ApiOperation(value = "web微信扫码登录首次绑定手机")
@ApiImplicitParams({
@ApiImplicitParam(name = "unionid", value = "微信unionid", required = true),
@ApiImplicitParam(name = "openid", value = "微信openid", required = true),
@ApiImplicitParam(name = "mobile", value = "手机号", required = true),
@ApiImplicitParam(name = "code", value = "验证码", required = true),
@ApiImplicitParam(name = "nickName", value = "昵称", required = false),
@ApiImplicitParam(name = "headimgurl", value = "头像", required = false)
})
@PostMapping("bindMobileByWebWx")
@IgnoreAuth
public ResponseInfo bindMobileByWebWx(String unionid, String openid, String mobile, String code, String nickName, String headimgurl, HttpServletRequest request){
BaseAssert.isBlankOrNull(unionid);
BaseAssert.isBlankOrNull(openid);
BaseAssert.isBlankOrNull(mobile);
BaseAssert.isBlankOrNull(code);
return loginService.bindMobileByWebwx(unionid, openid, mobile, code, nickName, headimgurl);
}
总结:步骤中发送http请求的方式有很多,可以自行选择,微信提供的接口参数填充重点是redirect_url这个参数必须要是可以供公网访问的域名地址,否则无法跳转。。。