@GetMapping("/callback") @ApiOperation("微信扫码确认后执行回调") public String callback(String code,String state){ //1、接收code值 //用code去请求微信的固定地址,得到accessToken和openId //向认证服务器发送请求换取access_token String baseAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token" + "?appid=%s" + "&secret=%s" + "&code=%s" + "&grant_type=authorization_code"; //带参数的真实认证服务器请求地址 String accessTokenUrl = String.format(baseAccessTokenUrl, ConstWxUtil.WX_OPEN_APP_ID, ConstWxUtil.WX_OPEN_APP_SECRET, code ); //2、请求认证服务器获取接口调用凭证access_token和用户唯一标识openId try { String accessTokenInfo = HttpClientUtils.get(accessTokenUrl); //将上述json字符串转换成map对象 /* { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } */ Gson gson = new Gson(); HashMap mapAccessTokenInfo = gson.fromJson(accessTokenInfo, HashMap.class); //取出的access_token String access_token = (String)mapAccessTokenInfo.get("access_token"); //取出的openid String openid = (String)mapAccessTokenInfo.get("openid"); //3、再通过获取出来的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 userInfo = HttpClientUtils.get(userInfoUrl); /* { "openid":"o3_SC5_eI--mIC9ikI2pvTuZhYnk", "nickname":"Kong", "sex":0, "language":"", "city":"", "province":"", "country":"", "headimgurl":"https:\/\/thirdwx.qlogo.cn\/mmopen\/vi_32\/hAqkcbxzEJzic0WYl9pHDglAvYBI4iagLsSLXb2ialcxa3Au6UmwibSiadGMtbQia0oAzmzq26k2f1ES4q1HbS6aIYuA\/132", "privilege":[], "unionid":"oWgGz1OqVll-tTU4R_DM_zRp7Rjc" } */ //将上面的json字符串转换成map对象 HashMap mapUserInfo = gson.fromJson(userInfo, HashMap.class); //扫码人基础信息 String nickname = (String)mapUserInfo.get("nickname"); String headImgurl=(String)mapUserInfo.get("headimgurl"); String openId=(String)mapUserInfo.get("openid"); //扫码后自动注册(入库) //先判断是否已注册 boolean isExist = memberService.getUserOpenId(openId); if(!isExist){ //入库 UcenterMember member = new UcenterMember(); member.setNickname(nickname); member.setOpenid(openid); member.setAvatar(headImgurl); memberService.save(member); } UcenterMember ucenterMember = memberService.getUserByOpenId(openId); String token = JwtUtils.getJwtToken(ucenterMember.getId(), ucenterMember.getNickname()); //因为端口号不同存在跨域问题,cookie不能跨域,所以这里使用url重写 return "redirect:http://localhost:3000?token="+token; } catch (Exception e) { e.printStackTrace(); throw new MyException(20010,"登录失败!"); } }
总结:
实现微信授权登录就好比开宝箱,一共需要3把钥匙,第一把钥匙是appid(这个需要在微信开放平台完成注册和认证由平台颁发);通过appid请求固定地址可以生成微信二维码;用户扫描二维码授权后拿到第二把钥匙code(随机唯一值);再通过code去请求固定服务器地址拿到第三把钥匙openid(用户唯一标识)和accessToken(访问凭证);最后再通过openid和accessToken请求固定地址拿到微信用户基本信息。