根据微信的官方文档,网页授权获取用户基本信息此接口是通过OAuth2.0来完成网页授权的,关于OAuth2.0是什么在这里不在累述,咱们的重点是微信用户通过公众账号点击菜单直接跳转到想要去的网页上,而我们的服务器端通过用户直接跳转到网页这个行为获取到微信用户的openid。
关于网页授权的两种scope的区别说明
1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。
特别说明:上述第一条提到了静默授权四个字很多初学者不理解,其实这四个字的意思就是用户点击菜单直接跳转到网页上,就像我们点击a链接直接跳转一样,用户没有任何感觉。反过来用户有感知的意思是直接跳转到微信的授权界面,询问用户是否授权,界面有个"同意授权"字样的按钮,只有用户点击这个按钮,才能进入想要去的网页。
接下来我们的示例是基于静默授权用户无感知这个方面。
第一首先我们登录微信公众平台管理中心-接口权限,配置域名。目前好像微信并不支持ip地址了。
第二、 自定义菜单设置
菜单json字符串设置这一步是必不可少的,json字符串如下:
{
"name": "网页授权",
"type": "view",
"url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxab1321a3sss28b&redirect_uri=http://www.xxxx.com/xxx项目名/weixin/xxx.do&response_type=code&scope=snsapi_base&state=1#wechat_redirect"
}
第三行t ype类型必须是view类型。
第四行 appid应用id,可在微信管理平台中心查询,redirect_uri为我们跳转的界面请求地址,www.xxx.com是我们第一步配置的域名,后面剩下的参数都是固定写法,不可更改。
把上述json提交生成公众号菜单
第三、 获取code
其实只要第二步自定义菜单的json字符串设置好了这一步很简单,只有一行代码,在上面的xxx.do方法中利用request对象直接获取
String code = request.getParameter("code");
System.out.println("获取的code::::"+code);
第四、获取用户的openid
网页授权方式获取openid我们除了上述三步设置,还需要另外两个参数,这两个参数我们经常见,那就是AppID(应用ID)和AppSecret(应用密钥),这两个参数我相信读者肯定很熟悉了,在这里就不在累述。
String appid = "";//应用id
String secret = "";//应用秘钥
String code="";//第三步获取的code
String weiUserJson=HttpUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&code="+code+"&grant_type=authorization_code", "utf-8", 30000);
JSONObject jsonOuth = JSONObject.fromObject(weiUserJson);
String openid=jsonOuth.getString("openid");
grant_type=authorization_code保持不变,但是也不要去掉。
HttpUtil的get方法:public static String sendGet(String url, String charset, int timeout)
{
String result = "";
try
{
URL u = new URL(url);
try
{
URLConnection conn = u.openConnection();
conn.connect();
conn.setConnectTimeout(timeout);
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
String line="";
while ((line = in.readLine()) != null)
{
result = result + line;
}
in.close();
} catch (IOException e) {
return result;
}
}
catch (MalformedURLException e)
{
return result;
}
return result;
}
代码示例完成了,只要把上述代码复制到我们在json字符串赋值的请求地址方法中即可获取openid,完整代码如下,
假如自定义菜单中的xxx.do请求到getUserOpenid()这个方法中,那么getUserOpenid()方法中获取openid如下
/***
* V型知识库 www.vxzsk.com
* @param request
* @return
*/
@RequestMapping(value="/xxx")
public String getUserOpenid(HttpServletRequest request){
System.out.println("获取的code::::"+request.getParameter("code"));
String appid = AppConst.APP_ID;
String secret = AppConst.APPSECRET;
String code=request.getParameter("code");
String weiUserJson=HttpUtil.sendGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+secret+"&code="+code+"&grant_type=authorization_code", "utf-8", 30000);
JSONObject jsonOuth = JSONObject.fromObject(weiUserJson);
String openid= jsonOuth.getString("openid");
System.out.println("openid:"+openid);
return "xx";
}
HttpUtil.sendGet方法代码已在第四步贴出,黏贴到工程里替换即可