首先大家要看下微信的API文档。
微信网页授权,获取用户的微信官方API文档地址:https://open.weixin.qq.com/
点击资源中心,查看微信登录文档
三次握手
微信认证流程(我自己简称三次握手):
1、用户同意授权,获取code
2、通过code换取网页授权access_token,用户openId等信息
3、通过access_token和用户的openId获取该用户的用户信息
第三方微信接口登录流程图:
用户扫描二维码
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
redirect_uri是用户允许授权后,将会重定向到redirect_uri的网址上,并且带上code和state参数
redirect_uri?code=CODE&state=STATE
若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数
redirect_uri?state=STATE
/** * 微信引导页进入的方法 * @return */ @RequestMapping("/loginByWeiXin") public String loginByWeiXin(HttpServletRequest request, Mapmap) { // 获取code和state 2 个参数 String code = request.getParameter("code"); String state = request.getParameter("state"); System.out.println("code -------" + code + ", state ------- " + state); if(code != null && !"".equals(code)) { // 授权成功, 获取用户token和openID OAuthInfo authInfo = WeiXinUtil.getAccess_token(code); String openid = authInfo.getOpenid(); String access_token = authInfo.getAccess_token(); if(access_token == null) { // Code 使用过 异常 System.out.println("Code 使用过 异常....."); return "redirect:" + 跳转的路径; } // 查询微信号是否绑定第三方平台 SysUser sysUser = weiXinService.getUserByWeiXinID(openid); if(sysUser == null) { //获取随机字符串长度是57的 String randomStr = StringUtil.getRandomString(57); request.getSession().setAttribute(openid, randomStr); // 尚未绑定账号 System.out.println("尚未绑定账号....."); return "redirect:/index.jsp?openid=" + openid + "&state=" + randomStr; } userController.doSomeLoginWorkToHomePage(sysUser.getMcid(), map); // 登录成功 return "homePage"; } // 未授权 return "redirect:" + 路径; }
根据code获取token(实体类OAuthInfo封装微信返回来的用户信息)
public static OAuthInfo getAccess_token(String code){ String authUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code "; authUrl= authUrl.replace("APPID", Param.APPID); authUrl = authUrl.replace("SECRET", Param.SECRET); authUrl = authUrl.replace("CODE", code); String jsonString = HTTPRequestUtil.sendPost(authUrl,""); System.out.println("jsonString: " + jsonString); OAuthInfo auth = null; try { auth = (OAuthInfo) JacksonUtil.parseJSONToObject(OAuthInfo.class, jsonString); } catch (Exception e) { e.printStackTrace(); } return auth; }
返回的用户信息格式:
{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" //客户授权后才会有这个字段 }