微信OAuth授权获取用户OpenId-JAVA(个人经验)
2014-07-21 16:51
856 查看
个人小程序。微信扫一扫查看哦。谢谢支持
https://open.weixin.qq.com/ 这个是授权登陆自己网站的和我的这个是有区别的。
带评论昵称 才同意加QQ
鉴于老是有人问我。就更新一下了。
更新时间 2018年08月06日
测试公众号地址:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
可以扫描关注查看效果。这个是测试号。
http://mp.weixin.qq.com/wiki这个是官网的接口文档
微信授权获取用户openid-JAVA
开发微信测试需要用到的代码和jar包都在里面 包括核心代码
源码一元一份(需要请加QQ:783021975)。语言为Java(Servlet) 实现功能 自定义菜单、自动回复、回调配置、OAuth接口实现、JSSDK实现
注意:授权把回调域名配置了。(只需要域名就行 例如:www.baidu.com)
没有配置回调域名有问题就别问我了。
JSSDK域名配置:
拉取用户信息(需scope为 snsapi_userinfo)
本作者是用菜单的方式引导用户进入点击获取信息的。不会创建菜单的自己去看官网API。或者搜索教程。先把官网文档稍微看下。知道自己需要配置的域名。等一些参数。点个赞都不给。就什么问题也问。还有。我工作不是专门做微信这方面的。我也需要忙我自己的工作内容。
如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。
前提设置一个菜单调用授权接口的URL获取code 方式很多。不一定非得是菜单引导。只要是如下地址就行。
修改相应的参数后的链接(只是一个例子) 创建一个view类型的菜单。url如下:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=自己账户的appid&redirect_uri=http://替换成自己的域名/wx/servlet&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect
CommonButton btn11 = new CommonButton(); btn11.setName("授权测试"); btn11.setType("view"); //这里替换成自己的域名服务器信息 http://xxx.com/wx/servlet wx为项目名称。这个根据自己的实际情况来。servlet为授权方法路径 如果需要改动请修改web.xml后再改动这里 String redirect_uri= "https://www.xsshome.cn/wx/servlet"; String redirect_uriencode= URLEncoder.encode(redirect_uri,"utf-8"); String oauth_url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="+Constants.appId+"&redirect_uri="+redirect_uriencode+"&response_type=code&scope=snsapi_base&state=HEAT#wechat_redirect"; btn11.setUrl(oauth_url);
截图示意
通过获取CODE得到OPENID请求获取用户基本信息(UnionID机制)接口得到相关信息
第一步:用户同意授权,获取code 引导用户进入授权的URL 修改一些参数
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认带有scope参数中的snsapi_base和snsapi_userinfo),引导关注者打开如下页面:本作者用菜单的方式引导用户点击进入。https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
我的代码如下:一个Servlet请求 获取code + 用户基本信息
/** * 回调的方法 获取到code 再根据相关参数获取用户信息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //接受参数 String code = request.getParameter("code"); String scope = request.getParameter("scope"); AccessTokenFactory accessToken = new AccessTokenFactory(); log.info("==============[OAuthServlet]获取网页授权code="+code+"==============[OAuthServlet]获取网页跳转权限="+scope); HttpSession session = request.getSession(); String openId = session.getAttribute("openid")==null?"":session.getAttribute("openid").toString(); if(null==openId||openId.equals("")){ if(null != code && !"".equals(code)){ log.info("==============[OAuthServlet]获取网页授权code不为空,code="+code); //第一步根据code换取openId 这一步拿到openid OAuthInfo oa = WeixinUtil.getOAuthOpenId(Constants.appId,Constants.appSecret,code); //第二步根据获取的openid 再用https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET接口获取token 换取微信用户基本信息 UserInfo info = WeixinUtil.getUserInfo(accessToken.getAccessToken().getToken(), oa.getOpenId()); if(!"".equals(oa) && null != oa){ log.info("==============[OAuthServlet]获取网页授权openID="+oa.getOpenId()); request.setAttribute("openid", oa.getOpenId()); //保存到session 防止用户刷新页面导致失败 session.setAttribute("openid", oa.getOpenId()); if(null!=info){ request.setAttribute("nickname", info.getNickname()); request.setAttribute("headimgurl", info.getHeadimgurl()); } request.getRequestDispatcher("/index.jsp").forward(request, response); }else{ log.info("==============[OAuthServlet]获取网页授权openId失败!"); } }else{ log.info("==============[OAuthServlet]获取网页授权code失败!"); } }else{ UserInfo info = WeixinUtil.getUserInfo(accessToken.getAccessToken().getToken(),openId); if(null!=info){ request.setAttribute("openid", openId); session.setAttribute("openid", openId); request.setAttribute("nickname", info.getNickname()); request.setAttribute("headimgurl", info.getHeadimgurl()); } request.getRequestDispatcher("/index.jsp").forward(request, response); } }
替换相应的APPID APPSECRET SCOPE
第一步:通过code获取openid
具体代码如下。code获取 openid值/** * 网页授权,根据code取得openId * @param appid 公众号的唯一标识 * @param secret 公众号的appsecret密钥 * @param code code为换取access_token的票据 * @return */ public static OAuthInfo getOAuthOpenId(String appid, String secret, String code ) { OAuthInfo oAuthInfo = null; String requestUrl = o_auth_openid_url.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code); System.out.println("==============requestUrl:"+requestUrl+"=============="); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); System.out.println("==============jsonObject:"+jsonObject+"=============="); // 如果请求成功 if (null != jsonObject) { try { oAuthInfo = new OAuthInfo(); oAuthInfo.setAccessToken(jsonObject.getString("access_token")); oAuthInfo.setExpiresIn(jsonObject.getInt("expires_in")); oAuthInfo.setRefreshToken(jsonObject.getString("refresh_token")); oAuthInfo.setOpenId(jsonObject.getString("openid")); oAuthInfo.setScope(jsonObject.getString("scope")); } catch (JSONException e) { oAuthInfo = null; // 获取token失败 log.error("网页授权获取openId失败 errcode:{} errmsg:{}", jsonObject .getInt("errcode"), jsonObject.getString("errmsg")); } } return oAuthInfo; }
这样子就会返回以下son格式数据
{ "expiresIn": 7200, "openId": "o2VKNju8JqCeGVoEWJ1S8Ue_up8E", "scope": "snsapi_base", "accessToken": "12_cAJ8dRiI7rkW-_1hqZyaaAO5lYNX9N9Hm_BUesKOL9Mg-F7P4Ie66l6Uypf-vl-DX1SgjP8TYVet_x13kc2IQQHaXAngilSu-0RVq_s6uGQ", "refreshToken": "12_dwEXNtSpeONSWMZrHjhPPCtpyRECSOzB43H8BEJi3JVrTFwcdmSJRLUhjw31rYuXQ181EGpyEciQ-Bf_fEuzkt8r2_dk0BwHTjeTlqZEizY" }
第二步:通过openid获取用户基本信息 这里的access_token为基础接口获取的access_token
获取access_token,access_token是公众号的全局唯一接口调用凭据 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET[/code]{ "expiresIn": 7200, "openId": "o2VKNju8JqCeGVoEWJ1S8Ue_up8E", "scope": "snsapi_base", "accessToken": "12_cAJ8dRiI7rkW-_1hqZyaaAO5lYNX9N9Hm_BUesKOL9Mg-F7P4Ie66l6Uypf-vl-DX1SgjP8TYVet_x13kc2IQQHaXAngilSu-0RVq_s6uGQ", "refreshToken": "12_dwEXNtSpeONSWMZrHjhPPCtpyRECSOzB43H8BEJi3JVrTFwcdmSJRLUhjw31rYuXQ181EGpyEciQ-Bf_fEuzkt8r2_dk0BwHTjeTlqZEizY" }
根据上面代码获取的access_token openid 然后再请求获取userinfo的接口。就能得到微信用户的所有信息了。//获取用户信息接口 public static String userinfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
获取用户信息代码如下。/** * 根据openid获取用户信息 * @param access_token 授权得到的access_token * @param openid 授权获取的openid * @return */ public static UserInfo getUserInfo(String access_token,String openid ) { UserInfo userInfo = null; String requestUrl = userinfo_url.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid); System.out.println("==============requestUrl:"+requestUrl+"=============="); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); System.out.println("==============jsonObject:"+jsonObject+"=============="); // 如果请求成功 if (null != jsonObject) { try { userInfo = new UserInfo(); userInfo.setNickname(jsonObject.getString("nickname")); userInfo.setHeadimgurl(jsonObject.getString("headimgurl")); } catch (JSONException e) { userInfo = null; // 获取token失败 log.error("网页授权获取openId失败 errcode:{} errmsg:{}", jsonObject .getInt("errcode"), jsonObject.getString("errmsg")); } } return userInfo; }
具体返回如下{ "country": "中国", "unionid": "oUmIot2Yo2Mb_8fVW3UVw9AW1w4Y", "qr_scene": 0, "subscribe": 1, "city": "海淀", "openid": "o2VKNju8JqCeGVoEWJ1S8Ue_up8E", "tagid_list": [ ], "sex": 1, "groupid": 0, "language": "zh_CN", "remark": "", "subscribe_time": 1533536600, "province": "北京", "subscribe_scene": "ADD_SCENE_QR_CODE", "nickname": "小帅丶", "headimgurl": "http://thirdwx.qlogo.cn/mmopen/Lj9cibm6LlmjNM8CGSYKuMQiaD4tTPwUjD7zVkkn2u6kFqv4zDwtcfHFntHyxtjjmXeicLDqVqQB42vUukxB5Mia8HgoV94gsN02/132", "qr_scene_str": "" }
这就获取到用户的基本信息,以上结果只适合用户关注了公众号信息获取。
并非https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842网址中的流程。后续补充文档中流程的获取步骤
参数说明
参数 | 说明 |
---|---|
subscribe | 用户是否订阅该公众号标识,值为0时,代表此用户没有关注该公众号,拉取不到其余信息。 |
openid | 用户的标识,对当前公众号唯一 |
nickname | 用户的昵称 |
sex | 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知 |
city | 用户所在城市 |
country | 用户所在国家 |
province | 用户所在省份 |
language | 用户的语言,简体中文为zh_CN |
headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 |
subscribe_time | 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间 |
{"errcode":40013,"errmsg":"invalid appid"}
1.OAuthServlet 对code进行access——token的验证
2.一个Servlet的方法调用接口地址。得到相应code。
3.OAuthInfo 返回数据相应的参数的PO类。set/get方法
4.WeiXinUtil添加一个方法 public OAuth getOAuthInfo(String appid, String secret, String code)得到json格式。并使用JSONObject读取出openid数据。
5.根据openid + token 获取已关注公众号的用户的基本信息
官方网页授权OAuth 获取CODE 换取OPENID 换取用户基本信息流程
基本与上面一致。为了能获取用户更多信息。scope建议为 snsapi_userinfo。代码如下:package cn.zxs.weixin.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import net.sf.json.JSONObject; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import cn.zxs.weixin.util.Constants; import cn.zxs.weixin.weixin.pojo.OAuthInfo; import cn.zxs.weixin.weixin.pojo.UserInfo; import cn.zxs.weixin.weixin.util.WeixinUtil; public class OAuthServletOff extends HttpServlet { private static final long serialVersionUID = 1L; private Log logger = LogFactory.getLog(getClass()); //走POST方式 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } //OAuth 官方流程 /** * 1 第一步:用户同意授权,获取code * 2 第二步:通过code换取网页授权access_token * 3 第三步:刷新access_token(如果需要) * 4 第四步:拉取用户信息(需scope为 snsapi_userinfo) */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //获取微信返回的code参数 //第一步:用户同意授权,获取code String code = request.getParameter("code"); //获取session是否有存在的openid logger.info("[OAuthServletOff]获取网页授权code="+code); String openId = session.getAttribute("openid")==null?"":session.getAttribute("openid").toString(); if(null==openId||openId.equals("")){ //第二步:通过code换取网页授权access_token OAuthInfo oAuthInfo = WeixinUtil.getOAuthOpenId(Constants.appId,Constants.appSecret,code); logger.info("通过code换取网页授权access_token接口返回的内容"+JSONObject.fromObject(oAuthInfo)); if(null!=oAuthInfo){ request.setAttribute("openid", oAuthInfo.getOpenId()); //如果第一次获取openid 则放在session里面 防止刷新页面导致提示code使用过错误 session.setAttribute("openid", oAuthInfo.getOpenId()); session.setAttribute("refresh_token", oAuthInfo.getRefreshToken()); //第四步:拉取用户信息(需scope为 snsapi_userinfo) 第三步非必须步骤哦 UserInfo userInfo = WeixinUtil.getOAuthUserInfo(oAuthInfo.getAccessToken(), oAuthInfo.getOpenId()); if(null!=userInfo){ request.setAttribute("nickname", userInfo.getNickname()); request.setAttribute("headimgurl", userInfo.getHeadimgurl()); request.getRequestDispatcher("/index.jsp").forward(request, response); }else{ logger.info("[OAuthServlet]获取用户信息失败!"); request.getRequestDispatcher("/index.jsp").forward(request, response); } } else { logger.info("[OAuthServlet]获取网页授权openId失败!"); request.getRequestDispatcher("/index.jsp").forward(request, response); } }else{ //第三步:刷新access_token(如果需要) String refresh_token = session.getAttribute("refresh_token").toString(); OAuthInfo oAuthInfo = WeixinUtil.getRefreshTokenInfo(Constants.appId,refresh_token); if(null!=oAuthInfo){ request.setAttribute("openid", oAuthInfo.getOpenId()); //如果第一次获取openid 则放在session里面 防止刷新页面导致提示code使用过错误 session.setAttribute("openid", oAuthInfo.getOpenId()); session.setAttribute("refresh_token", oAuthInfo.getRefreshToken()); //第四步:拉取用户信息(需scope为 snsapi_userinfo) 第三步非必须步骤哦 UserInfo userInfo = WeixinUtil.getOAuthUserInfo(oAuthInfo.getAccessToken(), oAuthInfo.getOpenId()); if(null!=userInfo){ request.setAttribute("nickname", userInfo.getNickname()); request.setAttribute("headimgurl", userInfo.getHeadimgurl()); request.getRequestDispatcher("/index.jsp").forward(request, response); }else{ logger.info("[OAuthServlet]获取用户信息失败!"); request.getRequestDispatcher("/index.jsp").forward(request, response); } } else { logger.info("[OAuthServlet]获取网页授权openId失败!"); request.getRequestDispatcher("/index.jsp").forward(request, response); } } } }
新加的2个方法 一个获取微信用户信息。一个是刷新操作获取用户信息(需要用到(refresh_token)
//获取用户信息接口 public static String OAUTH_USERINFO = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN"; /** * 网页授权获取用户信息 * @param access_token 授权得到的access_token * @param openid 授权获取的openid * @return */ public static UserInfo getOAuthUserInfo(String access_token,String openid) { UserInfo userInfo = null; String requestUrl = OAUTH_USERINFO.replace("ACCESS_TOKEN", access_token).replace("OPENID", openid); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); log.info("官方授权获取用户信息接口返回的内容"+jsonObject); // 如果请求成功 if (null != jsonObject) { try { userInfo = new UserInfo(); userInfo.setNickname(jsonObject.getString("nickname")); userInfo.setHeadimgurl(jsonObject.getString("headimgurl")); userInfo.setOpenid(jsonObject.getString("openid")); } catch (JSONException e) { userInfo = null; log.error("网页授权获取用户信息失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); } } return userInfo; } //刷新token public static String REFRESH_TOKEN_URL="https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN"; /** * 刷新获取的token * @param appid * @param refresh_token * @return */ public static OAuthInfo getRefreshTokenInfo(String appid,String refresh_token) { OAuthInfo oAuthInfo = null; String requestUrl = REFRESH_TOKEN_URL.replace("APPID", appid).replace("REFRESH_TOKEN", refresh_token); JSONObject jsonObject = httpRequest(requestUrl, "GET", null); log.info("getRefreshTokenInfo"+JSONObject.fromObject(jsonObject)); // 如果请求成功 if (null != jsonObject) { try { oAuthInfo = new OAuthInfo(); oAuthInfo.setAccessToken(jsonObject.getString("access_token")); oAuthInfo.setExpiresIn(jsonObject.getInt("expires_in")); oAuthInfo.setRefreshToken(jsonObject.getString("refresh_token")); oAuthInfo.setOpenId(jsonObject.getString("openid")); oAuthInfo.setScope(jsonObject.getString("scope")); } catch (JSONException e) { oAuthInfo = null; log.error("网页授权获取openId失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg")); } } return oAuthInfo; }
https://open.weixin.qq.com/ 这个是授权登陆自己网站的和我的这个是有区别的。
http://www.oschina.net/code/snippet_1444646_47662 HTTPREQUEST方法、
个人微博 http://weibo.com/u/2205636212
个人博客 http://my.oschina.net/xshuai/blog
微信/QQ 783021975 [b] 请先留言说明您!否则不加![/b]
相关文章推荐
- 微信OAuth授权获取用户OpenId-JAVA(个人经验)
- 微信OAuth授权获取用户OpenId-JAVA(个人经验)【申明:来源于网络】
- 微信OAuth授权获取用户OpenId-JAVA
- 微信OAuth授权获取用户OpenId-JAVA
- java 网页授权获取微信用户信息错误 40029 微信端会发出两次请求 错误的oauth第二次无效的code
- java实现微信授权获取用户openid及授权用户相关信息
- java 获取微信 页面授权 获取用户openid
- java 获取微信 页面授权 获取用户openid
- java获取点击微信自定义菜单的用户openid
- MVC微信网页授权获取用户OpenId
- 微信oauth网页授权获取用户基本信息
- java微信网页授权获取用户信息以及JSSDK自定义分享等功能<一>
- 通过微信网页授权获取用户OpenId(redirect_uri 参数错误)
- java微信网页授权获取用户信息以及JSSDK自定义分享等功能<二>
- 微信公众号开发-微信网页授权获取用户openid以及用户信息的步骤
- 微信公众号开发-微信网页授权获取用户openid以及用户信息的步骤
- java微信网页授权获取用户信息以及JSSDK自定义分享等功能<四>
- 微信oauth获取用户的信息页面授权
- java微信网页授权获取用户信息以及JSSDK自定义分享等功能<三>