说明:如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑。
1、授权回调域名
首先,先登录微信公众平台填写授权回调页面域名(可以申请公众平台测试账号进行开发),回调页面域名是你的第三方跳转域名,不需要加http,如截图所示:
2、授权流程分为4步:
a、引导用户进入授权页面同意授权,获取code
b、通过code换取网页授权access_token(与基础支持中的access_token不同)
c、如果需要,开发者可以刷新网页授权access_token,避免过期 (这一步可以省略)
d、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
3、流程演示例子
第一步:引导用户进入授权页面同意授权
点击链接: https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2toSetOpenidForWechat.do&response_type=code&scope=
snsapi_userinfo&state=STATE#wechat_redirect
参数讲解:appid是你的公众号的唯一标识appid,redirect_uri是你的跳转链接,必须要用urlEncode进行处理,我的跳转到我的项目中的是http://zy-ck.com/toSetOpenidForWechat.do,其他参数照着写,经过这一步后,微信端会返回一个code参数到我的toSetOpenidForWechat方法中
例子:
@RequestMapping(value = "/toSetOpenidForWechat", method = RequestMethod.GET)
public ModelAndView toSetOpenidForWechat(HttpServletRequest req, HttpServletResponse res ,String code) throws Exception {
//根据code获取用户的access_token和openid
ModelAndView view = new ModelAndView();
Session session = SecurityUtils.getSubject().getSession();
String urlForWechat = (String) session.getAttribute("urlForWechat");
net.sf.json.JSONObject userInfo = getToken(req, res, code);
view.addObject("openid", userInfo.getString("openid"));
view.setViewName("wechat/setOpenid");
return view;
}
第二步:通过code换取网页授权access_token和openid
用户点击授权后,获取到code,进行下一步处理,通过code换取网页授权access_token和openid,请求下面链接
链接:https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
参数讲解:code是你上一步获取的code,appid是你的公众号的唯一标识appid,secret是你的公众号的appsecret,其他参数照着写,经过这一步后,会返回一个access_token和openid参数
第三步:通过access_token和openid拉取用户信息
获取到access_token和openid参数,通过access_token和openid拉取用户信息,请求下面链接
链接:https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
参数讲解:access_token和openid参数是你上一步骤获取的参数,其他参数照着写,经过这一步后,微信会以json方式返回用户信息给你
正确时返回的JSON数据包如下:
{ "openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ
4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2" ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
以下是本人项目中的例子,由于第二步,第三步操作相同,所有我只写到一个方法中
例子:
public net.sf.json.JSONObject getToken(HttpServletRequest req,HttpServletResponse res,String code) throws Exception {
//获取微信服务appid和密码
String appid = "";//你公众号的appid
String appsecret = "";//你公众号的appsecret
//根据code获取用户的access_token和openid
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+appsecret+"&code="+code+"&grant_type=authorization_code";
net.sf.json.JSONObject json = AuthUtil.doGetJson(url);
String openid = json.getString("openid");
String token = json.getString("access_token");
//根据access_token和openid获取用户的信息
String infoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token="+token+"&openid="+openid+"&lang=zh_CN";
net.sf.json.JSONObject userInfo = AuthUtil.doGetJson(infoUrl);
System.out.println(userInfo);
return userInfo;
}
在代码中用到了一个工具类AuthUtil
package com.ed.login;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import net.sf.json.JSONObject;
public class AuthUtil {
public static JSONObject doGetJson(String url) throws ParseException, IOException{
JSONObject jsonObject = null;
//DefaultHttpClient client = new DefaultHttpClient();
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = null;
//HttpResponse response = null;
try {
response = httpclient.execute(httpGet);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
HttpEntity entity = response.getEntity();
if(entity != null){
String result = EntityUtils.toString(entity,"UTF-8");
jsonObject = JSONObject.fromObject(result);
}
httpGet.releaseConnection();
return jsonObject;
}
}
最后,你就能获取到用户信息了,本帖子例子举例的是应用授权作用域为scope=snsapi_userinfo(弹出授权页面,可通过openid拿到昵称、性别、所在地等),如有不明之处或写的不好地方,欢迎留言讨论