微信公众号开发中有时会有获取用户信息的需求。我这里是点击某个按钮直接获取用户的信息,不需要用户授权(就是所谓静默授权)。
主要分以下几步:
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;
}
}