微信公眾號獲取使用者資訊
微信公眾號開發中有時會有獲取使用者資訊的需求。我這裡是點選某個按鈕直接獲取使用者的資訊,不需要使用者授權(就是所謂靜默授權)。
主要分以下幾步:
1.在微信公眾平臺,公眾號設定中設定網頁授權域名;
2.請求網頁授權的介面獲得code(獲取openid必需的引數);
3.用拿到的 code 請求介面獲取openid(獲取使用者資訊必需的引數);
4.用openid 請求介面獲得使用者資訊。
第一步:設定網頁授權域名
登入微信公眾平臺,公眾號設定->功能設定->網頁授權域名,填寫公眾號的域名
注意:這塊需要將這個 MP_verify_XoBSPwGqusD1IVzI.txt 放置在域名伺服器,web專案的根目錄下,放置合適之後這塊才能儲存。
第二步:請求介面得到code
需要請求的介面是這個
appid是你微信公眾好號的appid
redirect_uri 這個是你要跳轉的後臺地址。
注意這裡的redirect_uri必須填寫成 域名+後臺訪問路徑 的形式
這塊我的需求是這樣的,我在微信公眾號某個頁面有個新增按鈕,點選按鈕請求後臺方法,在後臺方法中獲取到微信使用者的資訊,將使用者資訊傳到這個後臺方法要去的頁面。
本來這個後臺方法的請求url比如是 http://gs.gsssi.cn/wechat/addPage,那麼我在點選這個按鈕的 js 方法中之前是這麼寫的
location.href = "http://gs.gsssi.cn/wechat/addPage"
現在改成
location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的APPID&redirect_uri=http://gs.gsssi.cn/wechat/addPage&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
那麼在這個後臺方法中就可以取得 獲取openid所需的 code
@RequestMapping(value = "/addPage") public String addPage(Model model,HttpServletRequest request, HttpSession session){ //首先判斷一下session中,是否有儲存著的當前使用者的資訊,有的話,就不需要進行重複請求資訊 /** * 進行獲取openId,必須的一個引數,這個是當進行了授權頁面的時候,再重定向了我們自己的一個頁面的時候, * 會在request頁面中,新增這個欄位資訊, */ //第一步,得到code String code = request.getParameter("code"); WeixinUserInfo weixinUserInfo = null; try { if(session.getAttribute("weixinUser") != null){ weixinUserInfo = (WeixinUserInfo) session.getAttribute("weixinUser"); }else { //第二步 得到openId String openId = UserInfoUtil.getOpenId(code); //第三步 得到使用者資訊 weixinUserInfo = UserInfoUtil.getUserInfo(TokenUtil.getToken().getAccessToken(), openId); //將獲取到的使用者資訊,放入到session中 session.setAttribute("weixinUser", weixinUserInfo); } model.addAttribute("weixinUser", weixinUserInfo); } catch (Exception e) { e.printStackTrace(); } return "wechat/basAdvice/adviceSave"; }
第三步:得到openid
請求下面這個介面得到openid,code就是上一步已經獲取到。access_token傳入最新獲取到的access_token。
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
第四步:得到使用者資訊
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID
獲取openid和使用者資訊的我都封裝在了UserInfoUtil 類中。其中用到的access_token引數就是普通的access_token。自行寫方法實現。
UserInfoUtil 程式碼:
package com.gsww.hzz.util.wechat;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;
import net.sf.json.JSONObject;
/**
* 獲取微信使用者資訊工具類
*/
public class UserInfoUtil {
public final static String appid = "你的appid";
public final static String secret = "你的secret";
//獲取openId介面
public final static String GET_OPEN_ID_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+ "appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
//獲取微信使用者資訊 介面
public static final String GET_WEIXIN_USER_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID";
@Autowired
private static RestTemplate restTemplate;
/**
* 獲取openId
* @param session
* @param code
* @return
*/
public static String getOpenId(String code){
System.out.println("get openid");
String requestUrl = GET_OPEN_ID_URL.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code);
String openId = "";
try{
JSONObject json = JSONObject.fromObject(sendGet(requestUrl));
//System.out.println("responsejson ----"+json.toString());
//JSONObject json = JSONObject.fromObject(responseJson);
openId = json.get("openid").toString();
} catch(Exception e){
e.printStackTrace();
}
return openId;
}
/**
* 獲取使用者資訊
* @param accessToken
* @param openId
* @return
*/
public static WeixinUserInfo getUserInfo(String accessToken, String openId){
WeixinUserInfo userInfo = new WeixinUserInfo();
String requestUrl = GET_WEIXIN_USER_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
try{
JSONObject json = JSONObject.fromObject(sendGet(requestUrl));
//System.out.println("---userinfo==responsejson ----"+json);
//JSONObject json = JSONObject.fromObject(responseJson);
// 使用者的標識
userInfo.setOpenId(json.getString("openid"));
// 暱稱
userInfo.setNickname(json.getString("nickname"));
// 使用者的性別(1是男性,2是女性,0是未知)
userInfo.setSex(json.getInt("sex"));
// 使用者所在國家
userInfo.setCountry(json.getString("country"));
// 使用者所在省份
userInfo.setProvince(json.getString("province"));
// 使用者所在城市
userInfo.setCity(json.getString("city"));
// 使用者頭像
userInfo.setHeadImgUrl(json.getString("headimgurl"));
} catch(Exception e){
e.printStackTrace();
}
return userInfo;
}
//傳送GET請求
public static String sendGet(String url) {
String result = "";
BufferedReader in = null;
try {
String urlName = url;
URL realUrl = new URL(urlName);
URLConnection conn = realUrl.openConnection();// 開啟和URL之間的連線
conn.setRequestProperty("accept", "*/*");// 設定通用的請求屬性
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
conn.setConnectTimeout(4000);
conn.connect();// 建立實際的連線
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));// 定義BufferedReader輸入流來讀取URL的響應
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("傳送GET請求出現異常!" + e);
} finally {// 使用finally塊來關閉輸入流
try {
if (in != null) {
in.close();
}
} catch (IOException ex) {
System.out.println("關閉流異常");
}
}
return result;
}
}
WeixinUserInfo類(微信使用者資訊 bean)
package com.gsww.hzz.util.wechat;
/**
* 類名: WeixinUserInfo </br>
* 描述: 微信使用者的基本資訊 </br>
* 開發人員: souvc </br>
* 建立時間: 2015-11-27 </br>
* 釋出版本:V1.0 </br>
*/
public class WeixinUserInfo {
// 使用者的標識
private String openId;
// 關注狀態(1是關注,0是未關注),未關注時獲取不到其餘資訊
private int subscribe;
// 使用者關注時間,為時間戳。如果使用者曾多次關注,則取最後關注時間
private String subscribeTime;
// 暱稱
private String nickname;
// 使用者的性別(1是男性,2是女性,0是未知)
private int sex;
// 使用者所在國家
private String country;
// 使用者所在省份
private String province;
// 使用者所在城市
private String city;
// 使用者的語言,簡體中文為zh_CN
private String language;
// 使用者頭像
private String headImgUrl;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public int getSubscribe() {
return subscribe;
}
public void setSubscribe(int subscribe) {
this.subscribe = subscribe;
}
public String getSubscribeTime() {
return subscribeTime;
}
public void setSubscribeTime(String subscribeTime) {
this.subscribeTime = subscribeTime;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getHeadImgUrl() {
return headImgUrl;
}
public void setHeadImgUrl(String headImgUrl) {
this.headImgUrl = headImgUrl;
}
}