1.--------------------用户授权登录并获取code
授权登录方式有两个,一种为静默授权登录(scope=snsapi_base),一种为非静默授权登录(scope=snsapi_userinfo),区别为静默授权是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)特点:用户无感知,但是只能获取到用户的唯一标示openid和union id,无法拿到用户的微信头像、微信名称等个人信息;非静默授权这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
如果用户同意授权,页面将跳转至 redirect_uri并且携带"?code=CODE&state=STATE"
2.-----------------使用第一步获得的code换取access_token
参数说明
appid=APPID(公众号唯一标识)
secret=SECRET(公众号的appsecret)
code=CODE(第一步获取的code参数)
grant_type=authorization_code(无需更改)
返回结果(json格式数据)
{
"access_token": "e1nYJFpZuehfQH1buzHFZLb7onqs_wT1cudSdy9HRlnaMXFtFpRMNFOA0euK6UxPcItrSNbAQVcXDdthbLJYX0MdH1p7-tkZSKuGqBCxVc0",
"expires_in": 7200,
"refresh_token": "0iVsXn4O1rBCASbO7hx8VNVUVFM1RP2Q4xS0giegd4jlIsJYOjTJNZ0b4Dsh_xcoB02ZZ3bt0WH0a47LvjIEPjWUnESJCZyl6EtY_xYZdVs",
"openid": "o47Fa0mp9SRTf3eiKmqWm69BjG_8",
"scope": "snsapi_userinfo"
}
结果解释
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
scope 用户授权的作用域,使用逗号(,)分隔
3.-----------------使用access_token获取用户信息
-------详情参照微信官方文档,下面贴整合代码
@RequestMapping(value = "/AuthorizationGetUserInfo.json", produces = "application/json;charset=utf-8", method = RequestMethod.GET) @ResponseBody public void AuthorizationGetUserInfo(HttpSession session, HttpServletResponse resp, String code) throws IOException{ if(code == null){ log.info("code为空==="); } String url = " https://api.weixin.qq.com/sns/oauth2/access_token"; String access_tokenUrl = "appid=appid" + "&secret=secret" + "&code=" + code + "&grant_type=authorization_code";//通过code换取网页授权access_token路径 String result = HttpRequest.sendGet(url, access_tokenUrl); Map<String, String> map = WXPayUtil.MapConversion(result); String access_token = map.get("access_token"); String openid = map.get("openid"); String surl = "https://api.weixin.qq.com/sns/userinfo"; String userinfoUrl = "access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN"; String sresult = HttpRequest.sendGet(surl, userinfoUrl); Map<String, String> userinfoMap = WXPayUtil.MapConversion(sresult); //标准json格式的String转json String str = userinfoMap.get("nickname"); try { userinfoMap.put("nickname", EmojiUtil.resolveToByteFromEmoji(str)); log.info("用户头像表情转化成字符" + userinfoMap.get("nickname")); } catch (Exception e) { log.info("用户信息拉取失败========================="); log.info("用户信息拉取失败=========================" + e.getMessage()); } String suOpenid = vipMapperService.ByOpenIdQueVip(openid);//查询用户表中的openid log.info("session的ID" + session.getId()); if (suOpenid != null && suOpenid != "") { User user = vipMapperService.selectVipInfo(userinfoMap); if (!user.getUuser().equals(userinfoMap.get("nickname"))) { userinfoMap.put("nickname", user.getUuser());//修改为新的昵称 } if (!user.getHeadimgurl().equals(userinfoMap.get("headimgurl"))) { userinfoMap.put("headimgurl", user.getHeadimgurl());//修改为新的头像 } Integer Upresult = vipMapperService.ByWXUpVip(userinfoMap);//修改会员 if (Upresult < 0) { log.info("修改会员失败了!"); } } else { //该openid用户表中不存在,新增用户 Integer Addresult = vipMapperService.AddVip(userinfoMap); if (Addresult < 0) { log.info("新增会员失败了===!"); } } Integer Uid = vipMapperService.ByOpenIdQuUid(openid); Cookie cookie = new Cookie("Uid", String.valueOf(Uid)); resp.addCookie(cookie); resp.sendRedirect(NowData.PROTOCOL + NowData.DOMAIN + "/WeChatpn/index.html#/mall"); } ---------------------------------utils /** * 向指定URL发送GET方法的请求 * * @param url * 发送请求的URL * @param param * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { //System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } /** * String转Map<String, String> * map * * @return */ public static Map<String, String> MapConversion(String str) { Map<String, Object> map = JSON.parseObject(str); Map<String, String> NewMap = new HashMap<String, String>(); for (String string : map.keySet()) { NewMap.put(string, map.get(string).toString()); } return NewMap; } /** * 利用正则表达式判断str是否存在表情字符 * @param str * @return */ public static String resolveToByteFromEmoji(String str) { Pattern pattern = Pattern .compile("[^(u2E80-u9FFF\w\s`~!@#\$%\^&\*\(\)_+-?()——=\[\]{}\|;。,、《》”:;“!……’:‘"<,>\.?/\\*)]"); Matcher matcher = pattern.matcher(str); StringBuffer sb2 = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb2, encode(matcher.group(0))); } matcher.appendTail(sb2); //将分隔符 替换成 得到的内容就是 u1245 return sb2.toString().replace("&ns;","\"); }