微信OAuth授权获取用户OpenId-JAVA(个人经验)

https://open.weixin.qq.com/

最新博文在这里:https://my.oschina.net/xshuai/blog/293458

带评论昵称  才同意加QQ

‍鉴于老是有人问我。就更新一下了。

更新时间 2016年10月18日

修改了测试号权限不足导致授权获取信息抛异常的问题。

服务器暂时有问题。想查看效果。在周一到周五10:00-17:00查看即可。

可以扫描关注查看效果。这个是测试号。服务器有限。不要恶意攻击

http://mp.weixin.qq.com/wiki这个是官网的接口文档

微信授权获取用户openid-JAVA

开发微信测试需要用到的代码和jar包都在里面  包括核心代码

源码在这里。https://zb.oschina.net/market/opus/1444646_161 维护服务器。一份5元。自愿购买

链接: https://zb.oschina.net/market/opus/1444646_161

注意:授权把回调域名配置了。(只需要域名就行 例如:www.baidu.com)

没有配置回调域名有问题就别问我了。

拉取用户信息(需scope为 snsapi_userinfo)

本作者是用菜单的方式引导用户进入点击获取信息的。不会创建菜单的自己去看官网API。或者搜索教程。先把官网文档稍微看下。知道自己需要配置的域名。等一些参数。点个赞都不给。就什么问题也问。还有。我工作不是专门做微信这方面的。我也需要忙我自己的工作内容。

如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。

前提设置一个菜单调用授权接口的URL获取code

修改相应的参数后的链接(只是一个例子) 创建一个view类型的菜单。url如下:

 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx2d39c6c31ed5f199&redirect_uri=http://zxshuai.imwork.net/weixin/oauth.do                &response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect

截图示意(最后一张上传于2016年10月18日)

第一步:用户同意授权,获取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取得openId
     * 
     * @param appid   公众号的唯一标识
     * @param secret    公众号的appsecret密钥
     * @param code    code为换取access_token的票据          
     * @return 
     */public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //参数
        String code = request.getParameter("code");

        
        if(null != code && !"".equals(code)){
            log.info("==============[OAuthServlet]获取网页授权code不为空,code="+code);
            //根据code换取openId
            OAuthInfo oa = WeixinUtil.getOAuthOpenId(Constants.appId,Constants.appSecret,code);
            UserInfo info = WeixinUtil.getUserInfo(oa.getAccessToken(), oa.getOpenId());
            if(!"".equals(oa) && null != oa){
                 request.setAttribute("openid", oa.getOpenId());
                 request.setAttribute("nickname", info.getNickname());
                 request.getRequestDispatcher("/index.jsp").forward(request, response);
                 
            }else{
                log.info("==============[OAuthServlet]获取网页授权openId失败!");
            }
        }else{
            log.info("==============[OAuthServlet]获取网页授权code失败!");
        }
    }

替换相应的APPID APPSECRET SCOPE

第二步:通过code换取网页授权access_token  这里的access_token与基础获取的access_token不同

获取code后,请求以下链接获取access_token: 
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

具体做法与上面基本一致。更换相对应的值。需要注意的是code可以写一个Servlet获取。String code = request.getParameter("code");get/post都可以。

这样子就会返回一下json格式数据

{
   "access_token":"ACCESS_TOKEN",
   "expires_in":7200,
   "refresh_token":"REFRESH_TOKEN",
   "openid":"OPENID",
   "scope":"SCOPE"
}

具体代码如下。获取的code换取的access_token

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code;
    public static OAuthInfo getOAuthOpenId(String appid, String secret, String code ) {
        OAuthInfo oAuthInfo = null;
        String o_auth_openid_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code;";
        String requestUrl = o_auth_openid_url.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code);
       
        JSONObject jsonObject = httpRequest(requestUrl, "GET", null);
        
        //oAuthInfo是作者自己把那几个属性参数写在一个类里面了。
        // 如果请求成功
        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;
    }

根据上面代码获取的access_token  openid 然后再请求获取userinfo的接口。就能得到微信用户的所有信息了。

具体返回如下。获取用户信息代码不再写。

 请求获取用户信息的接口地址
{"sex":1,
"nickname":"小帅",
"privilege":[],
"province":"北京",
"openid":"o2VKNju8JqCeGVoEWJ1S8Ue_up8E",
"language":"zh_CN",
"headimgurl":"http://wx.qlogo.cn/mmopen/ribqo6CmxxhyfrokJWjVAedZzl590B4HAbribNVS3CQvplHp8KgmH1kIfqpM4Ek5uTr0lFW8yMDjfZrWLtvjjKLXu1H5icSfRBl/0",
"country":"中国",
"city":"海淀"}

这就获取到用户的openid。应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)我自己用的作用域为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

替换链接里面的大写字母的信息为你自己公众号的。state可以不改。

写一个Servlet专门接收传递过来的code。进行相应的操作。

获取用户基本信息接口

接口调用请求说明

http请求方式: GET
https://api.weixin.qq.com/cgi-bin/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

最新更新。2016年9月9日  鉴于好多人只能获取到openid但拿不到用户信息。那就更新一下。

通过openid是可以直接再去获取到用户信息的。前提也是用户关注了公众号

{
    "subscribe": 1,
    "openid": "osdhfjkdsfh78sdjkljljkkj",
    "nickname": "小帅帅丶",
    "sex": 1,
    "language": "zh_CN",
    "city": "北京",
    "province": "北京",
    "country": "中国",
    "headimgurl": "http://wx.qlogo.cn/mmopen/Kkv3HV30gbEZmoo1rTrP4UjRRqzsibUjT9JClPJy3gzo0NkEqzQ9yTSJzErnsRqoLIct5NdLJgcDMicTEBiaibzLn34JLwficVvl6/0",
    "subscribe_time": 1389684286
}

参数说明

参数

说明

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

用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间

错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}

具体代码 获取到openid代码在上面。都不愿意资助一下。就不要加QQ咨询所有的问题。

/**
	 * 网页授权获取用户信息
	 * @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"));
                                //等一系列的信息
			} catch (JSONException e) {
				userInfo = null;
				// 获取token失败
				log.error("网页授权获取openId失败 errcode:{} errmsg:{}", jsonObject
						.getInt("errcode"), jsonObject.getString("errmsg"));
			}
		}
		return userInfo;
	}
}

1.OAuthServlet 对code进行access——token的验证

2.一个Servlet的方法调用接口地址。得到相应code。

3.OAuthInfo 返回数据相应的参数的PO类。set/get方法

4.WeiXinUtil添加一个方法 publicOAuth  getOAuthInfo(String appid, String secret, String code)得到json格式。并使用JSONObject读取出自己想要的数据。

https://open.weixin.qq.com/ 这个是授权登陆自己网站的和我的这个是有区别的。

http://www.oschina.net/code/snippet_1444646_47662 HTTPREQUEST方法、

个人博客 http://my.oschina.net/xshuai/blog

微信/QQ  783021975 请先留言说明您!否则不加!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

popupwindow和listview

在使用PopupWindow的时候,有一个不好的地方就是不太好设置弹出窗体的大小。如果指定绝对大小,那么对于不同分辨率不同尺寸的手机来说,显示出来效果会不同,...

317100
来自专栏精讲JAVA

关于垃圾回收被误解的 7 件事

(点击上方公众号,可快速关注) ImportNew - 蒋 生武 对Java垃圾回收最大的误解是什么?它实际又是什么样的呢? 当我还是小孩的时候,父母常说如果你...

21570
来自专栏向治洪

使用lrucache和diskLrucache实现照片墙

其实,在真正的项目实战当中如果仅仅是使用硬盘缓存的话,程序是有明显短板的。而如果只使用内存缓存的话,程序当然也会有很大的缺陷。因此,一个优秀的程序必然会将内存...

26590
来自专栏向治洪

Android 使用android-support-multidex解决Dex超出方法数的限制问题

随着应用不断迭代,业务线的扩展,应用越来越大(比如集成了各种第三方sdk或者公共支持的jar包,项目耦合性高,重复作用的类越来越多),相信很多人都遇到过如下的...

42280
来自专栏向治洪

android fragement报nullexcption错误

这题目起的够骚情了,原创傲慢的上校哦,转载请标明:http://blog.csdn.net/aomandeshangxiao/article/details/7...

21570
来自专栏IT技术精选文摘

深入JDK源码之ThreadLocal类

ThreadLocal概述 学习JDK中的类,首先看下JDK API对此类的描述,描述如下: 该类提供了线程局部 (thread-local) 变量。这些变量不...

24650
来自专栏精讲JAVA

类加载器详解

内容:转自 java知音 类加载器是负责将可能是网络上、也可能是磁盘上的class文件加载到内存中。并为其生成对应的java.lang.class对象。一旦一...

22750
来自专栏IT技术精选文摘

协同过滤推荐算法Java代码实现

什么是协同过滤 协同过滤是利用集体智慧的一个典型方法。要理解什么是协同过滤 (Collaborative Filtering, 简称 CF),首先想一个简单的问...

1.3K60
来自专栏精讲JAVA

Netty 实现原理浅析

(点击上方公众号,可快速关注) 来源:kafka0102的博客 , www.kafka0102.com/2010/06/167.html Netty是JBoss...

30280
来自专栏精讲JAVA

你真的很熟分布式和事务吗?

微吐槽 hello,world. 不想了,我等码农,还是看看怎么来处理分布式系统中的事务这个老大难吧! 本文略长,读者需要有一定耐心,如果你是高级码农或者架构师...

22590

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励