微信公眾號授權回調用戶信息,獲取openid


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM