赞
踩
一.在页面加入标签
1.在登录页准备微信登录的按钮
<li><a href="https://open.weixin.qq.com/connect/qrconnect? appid=wxd853562a0548a7d0&redirect_uri=http://bugtracker.itsource.cn/callback.html &response_type=code&scope=snsapi_login&state=1#wechat_redirect"><i class="am-icon-weixin am-icon-sm"></i><span>微信登录</span> </a></li>
2.当用户点击微信扫码登录,向微信发起获取授权的请求
网址是,这个是为了获取code授权码的https://open.weixin.qq.com/connect/qrconnect? appid=wxd853562a0548a7d0&redirect_uri=http://bugtracker.itsource.cn/callback.html &response_type=code&scope=snsapi_login&state=1#wechat_redirect"><i class="am-icon-weixin am-icon-sm
redirect_uri=http://bugtracker.itsource.cn/callback.html 这个是回调域,授权成功后跳转的页面
3.微信收到确认,生成code(授权码),通过回调域拼接code返回,就获取到了code授权码了,
二.页面获取了code后,携带这个code发送请求到后台
1.后端接收请求和参数,在业务层处理请求
//code不为空 String code = map.get("code"); if(StringUtils.isEmpty(code)){ throw new MyException("系统异常。。。。"); } String url = WxConstants.GET_TOKEN_URL.replace("APPID", WxConstants.APPID) .replace("SECRET", WxConstants.SECRET) .replace("CODE", code); //根据code发送请求从微信获取token /*{ 返回的是这个对象 "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }*/ String obj = HttpClientUtils.httpGet(url); JSONObject jsonObject = JSONObject.parseObject(obj); //获取里面的token和openid String token = jsonObject.getString("access_token"); String openid = jsonObject.getString("openid");
首先code不能为空,判断非空
再发送第二个请求,将第一步获取的code携带进去,然后获取token和openid
2.判断openid是否存在,通过查询数据库微信登录的表
2.1.如果已经有了并且userid不为空,直接免密登录
WxUser wxUser = wxUserMapper.loadByOpenId(openid); String param = "?token="+token+"&openid="+openid; if(wxUser!=null && wxUser.getUser_id()!=null){//之前登录过,直接放行 //查询对应的logininfo信息 Logininfo logininfo = logininfoMapper.loadByUserId(wxUser.getUser_id()); //登录过,将用户信息存到redis //把用户信息放到redis key token String token1 = UUID.randomUUID().toString(); //logininfo对象要存入数据库,必须序列化 redisTemplate.opsForValue().set(token1, logininfo, 30, TimeUnit.MINUTES); Map<String, Object> map1 = new HashMap<>(); map1.put(Constant.TOKEN, token1); //把私密信息设置为空 logininfo.setPassword(null); logininfo.setSalt(null); map1.put(Constant.LOGININFO, logininfo); //map1.put("param", param); return AjaxResult.createSuccess(map1); }
2.2如果为空,需要让用户绑定个人用户信息
返回token+openId 前端帮我们跳转到绑定页面
return AjaxResult.createError("", param);
前端处理
let param = result.data; //没有绑定,跳转到绑定页面 location.href="http://bugtracker.itsource.cn/binder.html"+param;
3.binder.html页面解析地址栏参数并且接收用户输入的参数
3.1发起微信绑定流程
phone verifyCode token openId
3.2后端接收参数交给service处理
String phone = map.get("phone"); String verifyCode = map.get("verifyCode"); String accessToken = map.get("accessToken"); String openId = map.get("openId"); //1.空校验 if(StringUtils.isEmpty(phone) ||StringUtils.isEmpty(verifyCode) ||StringUtils.isEmpty(accessToken) ||StringUtils.isEmpty(openId)){ throw new MyException("信息不能为空"); } //2.判断验证码 //4.验证码是否过期 三分钟 Object o = redisTemplate.opsForValue().get(Constant.BINDER + phone); if(o==null){ throw new MyException("验证码已失效,请重新获取。。。"); } //5.前端输入的验证码和发送的是否一致 String code = o.toString().split(":")[0]; if(!verifyCode.equalsIgnoreCase(code)){ throw new MyException("验证码错误,请重新输入"); }
判断手机号是否注册过
//二:判断phone是否被注册 user User user = userMapper.loadByPhone(phone); User user1 = null; Logininfo logininfo = null; if(user!=null){ //1.如果注册了,那么我们可以直接绑定微信用户了 user1= user; logininfo = logininfoMapper.loadByUserId(user1.getId()); }else { //2.如果没有注册过,生成t_user + t_loginInfo + wxuser 三张表 user1 = initUser(phone); logininfo = initLogininfo(user1); //保存 logininfo.setType(1); logininfoMapper.save(logininfo); user1.setLogininfo_id(logininfo.getId()); userMapper.save(user1); }
通过 token+openId 查询微信信息 wxuser 生成t_wxuser
//获取用户信息,保存在wxuser中 //https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID String obj = HttpClientUtils.httpGet(WxConstants.GET_USER_URL.replace("ACCESS_TOKEN", accessToken) .replace("OPENID", openId)); WxUser wxUser = initWxuser(obj); //绑定 wxUser.setUser_id(user1.getId()); wxUserMapper.save(wxUser); //把用户信息放到redis key token String token = UUID.randomUUID().toString(); //logininfo对象要存入数据库,必须序列化 redisTemplate.opsForValue().set(token, logininfo, 30, TimeUnit.MINUTES); Map<String, Object> map2 = new HashMap<>(); map.put(Constant.TOKEN, token); //把私密信息设置为空 logininfo.setPassword(null); logininfo.setSalt(null); map2.put(Constant.LOGININFO, logininfo); return map2;
4.免密登录
完成
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。