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;","\\"); }