java 移动端网页_Java企业微信开发_09_身份验证之移动端网页授权(有完整项目源码)...

一、本节要点

1.1 授权回调域(可信域名)

在开始使用网页授权之前,需要先设置一下授权回调域。这里瞬间想到之前做JSSDK的时候,也设置过一个域名。二者本质上都是设置可信域名。

当用户授权完毕之后,请求将重定向到此域名(或者子域名)下的执行者(jsp页面或者servlet等)。如何设置授权回调域,请见第二节。

1.2 获取Code

https://open.weixin.qq.com/connect/oauth2/authorize?appid=CORPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&agentid=AGENTID&state=STATE#wechat_redirect

可将根据此链接生成一个view菜单按钮,用户点击此按钮时,将跳转到授权页面,授权成功后,页面重定向到指定的REDIRECT_URI页面,同时带上code和state请求参数,即页面将跳转至 redirect_uri?code=CODE&state=STATE页面。

1.3 移动端网页授权流程

(1)用户点击1.2中菜单按钮,跳转至授权页面

(2)用户授权成功,页面重定向到 redirect_uri?code=CODE&state=STATE 页面

(3)接收code,根据code获取成员信息(UserId,user_ticket)

(4)拿到UserId后可选择去根据UserId获取成员详细信息, 参见Java企业微信开发_02_通讯录同步 中的 Contacts_UserService类

(5) 拿到 user_ticket后可选择去使用user_ticket获取成员详情(其中包括用户头像)

在此我们只关注于打通 企业微信官方文档中 移动端网页授权 相关的接口,这是基础,至于实际工作中企业是如何去具体实现他们自己的授权业务,暂时不在我们讨论的范围内。

二、代码实现

2.1设置可信域名(授权回调域)

登录企业微信后台—>企业应用—>自建应用中的你的具体应用—>企业微信授权登录—>Web网页

5d29c63ce281f53e2cff566a3ef668af.png

a87a3493f954b598631eb40cbca7e03e.png

2.2 生成菜单按钮

添加一个用于网页授权的菜单按钮,运行MenuTest.testCreateMenu()方法生成按钮。

在已经成功生成菜单按钮时,有时可能出现菜单没有及时更新的情况,这时可以通过取消关注企业号,再重新关注企业号来解决这个问题。

(1)MenuService.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.ray.service;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importcom.google.gson.Gson;importcom.ray.pojo.menu.Button;importcom.ray.pojo.menu.CommonButton;importcom.ray.pojo.menu.ComplexButton;importcom.ray.pojo.menu.Menu;importcom.ray.pojo.menu.ViewButton;importcom.ray.util.WeiXinUtil;importnet.sf.json.JSONObject;public classMenuService {private static Logger log = LoggerFactory.getLogger(MenuService.class);//菜单创建(POST) 限100(次/天)

public static String create_menu_url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN&agentid=AGENTID";/*** 1.创建菜单

*

*@parammenu 菜单实例

*@paramaccessToken 有效的access_token

*@return0表示成功,其他值表示失败*/

public void createMenu(String accessToken,Menu menu,intagentId) {//1.获取json字符串:将Menu对象转换为json字符串

Gson gson = newGson();

String jsonMenu=gson.toJson(menu); //使用gson.toJson(user)即可将user对象顺序转成json

System.out.println("jsonMenu:"+jsonMenu);//2.获取请求的url

create_menu_url = create_menu_url.replace("ACCESS_TOKEN", accessToken)

.replace("AGENTID", String.valueOf(agentId));//3.调用接口,发送请求,创建菜单

JSONObject jsonObject = WeiXinUtil.httpRequest(create_menu_url, "POST", jsonMenu);

System.out.println("jsonObject:"+jsonObject.toString());//4.错误消息处理

if (null !=jsonObject) {if (0 != jsonObject.getInt("errcode")) {

log.error("创建菜单失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));

}

}

}/*** 2.组装菜单数据

*

*@return

*/

publicMenu getMenu() {/*ViewButton btn11 = new ViewButton();

btn11.setName("添加报销单");

btn11.setType("view");

btn11.setUrl("http://5nffqn.natappfree.cc/WeiXin_QiYe_Demo/uploadExpenseAccaout.jsp");*/ViewButton btn11= newViewButton();

btn11.setName("JSSDK多图上传");

btn11.setType("view");

btn11.setUrl("http://zvuntx.natappfree.cc/WeiXin_QiYe_Demo/JSSDKUploadPics.jsp");

ViewButton btn21= newViewButton();

btn21.setName("JSSDK测试(全)");

btn21.setType("view");

btn21.setUrl("http://zvuntx.natappfree.cc/WeiXin_QiYe_Demo/jsapiTicktAll.jsp");

ViewButton btn22= newViewButton();

btn22.setName("PC端网页授权");

btn22.setType("view");

btn22.setUrl("https://open.work.weixin.qq.com/wwopen/sso/qrConnect?appid=ww92f5da92bb24696e&agentid=1000002&redirect_uri=http%3A%2F%2Fzvuntx.natappfree.cc%2FWeiXin_QiYe_Demo%2FPCAuthorization.jsp&state=state");

ViewButton btn23= newViewButton();

btn23.setName("移动端网页授权");

btn23.setType("view");

btn23.setUrl("https://open.weixin.qq.com/connect/oauth2/authorize?appid=ww92f5da92bb24696e&redirect_uri=http%3A%2F%2Fzvuntx.natappfree.cc%2FWeiXin_QiYe_Demo%2FMTAuthorization.jsp&response_type=code&scope=snsapi_privateinfo&agentid=1000002&state=hec#wechat_redirect");

CommonButton btn12= newCommonButton();

btn12.setName("扫一扫");

btn12.setType("click");

btn12.setKey("12");

CommonButton btn13= newCommonButton();

btn13.setName("翻译功能");

btn13.setType("click");

btn13.setKey("13");

ViewButton btn14= newViewButton();

btn14.setName("上传图片");

btn14.setType("view");

btn14.setUrl("http://5nffqn.natappfree.cc/WeiXin_SanFenBaiXue/uploadimg.jsp");

ViewButton btn15= newViewButton();

btn15.setName("上传图片2");

btn15.setType("view");

btn15.setUrl("http://5nffqn.natappfree.cc/WeiXin_SanFenBaiXue/index2.jsp");

CommonButton btn24= newCommonButton();

btn24.setName("人脸识别");

btn24.setType("click");

btn24.setKey("24");

CommonButton btn25= newCommonButton();

btn25.setName("聊天唠嗑");

btn25.setType("click");

btn25.setKey("25");

CommonButton btn31= newCommonButton();

btn31.setName("Q友圈");

btn31.setType("click");

btn31.setKey("31");

CommonButton btn33= newCommonButton();

btn33.setName("幽默笑话");

btn33.setType("click");

btn33.setKey("33");

CommonButton btn34= newCommonButton();

btn34.setName("用户反馈");

btn34.setType("click");

btn34.setKey("34");

CommonButton btn35= newCommonButton();

btn35.setName("关于我们");

btn35.setType("click");

btn35.setKey("35");

ViewButton btn32= newViewButton();

btn32.setName("周边搜索");

btn32.setType("view");

btn32.setUrl("http://liufeng.gotoip2.com/xiaoqrobot/help.jsp");

ComplexButton mainBtn1= newComplexButton();

mainBtn1.setName("正在做功能");

mainBtn1.setSub_button(newButton[] { btn11, btn12, btn13, btn14, btn15 });

ComplexButton mainBtn2= newComplexButton();

mainBtn2.setName("测试");

mainBtn2.setSub_button(newButton[] { btn21, btn22, btn23, btn24, btn25 });

ComplexButton mainBtn3= newComplexButton();

mainBtn3.setName("更多");

mainBtn3.setSub_button(newButton[] { btn31, btn33, btn34, btn35, btn32 });/*** 这是企业号目前的菜单结构,每个一级菜单都有二级菜单项

*

* 在某个一级菜单下没有二级菜单的情况,menu该如何定义呢?

* 比如,第三个一级菜单项不是“更多体验”,而直接是“幽默笑话”,那么menu应该这样定义:

* menu.setButton(new Button[] { mainBtn1, mainBtn2, btn33 });*/Menu menu= newMenu();

menu.setButton(newButton[] { mainBtn1, mainBtn2, mainBtn3 });returnmenu;

}

}

View Code

(2)MenuTest.java

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.ray.test;importorg.junit.Test;importcom.ray.pojo.menu.Menu;importcom.ray.service.MenuService;importcom.ray.util.WeiXinParamesUtil;importcom.ray.util.WeiXinUtil;public classMenuTest {

@Testpublic voidtestCreateMenu(){//1.组装菜单

MenuService ms=newMenuService();

Menu menu=ms.getMenu();//2.获取access_token:根据企业id和应用密钥获取access_token

String accessToken=WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.agentSecret).getToken();

System.out.println("accessToken:"+accessToken);//3.创建菜单

ms.createMenu( accessToken, menu, WeiXinParamesUtil.agentId);

}

}

View Code

2.3 移动端网页授权业务类——MTAuthorizationService.java

包括两个方法:

(1)根据code获取成员信息

(2)使用userTicket获取成员详情

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

packagecom.ray.service;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importcom.google.gson.Gson;importcom.ray.pojo.UserTicket;importcom.ray.util.WeiXinUtil;importnet.sf.json.JSONObject;/*** @desc : 移动端网页授权Service

*

*@author: shirayner

* @date : 2017年9月14日 下午12:18:38*/

public classMTAuthorizationService {private static Logger log = LoggerFactory.getLogger(MenuService.class);public static final String GET_USERINFO_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token=ACCESS_TOKEN&code=CODE";public static final String GET_USERDETAIL_URL = "https://qyapi.weixin.qq.com/cgi-bin/user/getuserdetail?access_token=ACCESS_TOKEN";/**1.根据code获取成员信息

* @desc :GET请求、

* 成员信息包括

* UserId 成员UserID

* DeviceId 手机设备号(由企业微信在安装时随机生成,删除重装会改变,升级不受影响)

* user_ticket 成员票据,最大为512字节。scope为snsapi_userinfo或snsapi_privateinfo,且用户在应用可见范围之内时返回此参数。

* 后续利用该参数可以获取用户信息或敏感信息。

* expires_in user_token的有效时间(秒),随user_ticket一起返回

*

*@paramaccessToken

*@paramcode void*/

publicJSONObject getUserInfo(String accessToken,String code) {//1.获取请求的url

String get_userInfo_url=GET_USERINFO_URL.replace("ACCESS_TOKEN", accessToken)

.replace("CODE", code);//2.调用接口,发送请求,获取成员信息

JSONObject jsonObject = WeiXinUtil.httpRequest(get_userInfo_url, "GET", null);

System.out.println("jsonObject:"+jsonObject.toString());//3.错误消息处理

if (null !=jsonObject) {if (0 != jsonObject.getInt("errcode")) {

log.error("获取成员信息失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));

}

}returnjsonObject;

}/**2.使用userTicket获取成员详情

* @desc :POST请求

*

*@paramaccessToken

*@paramuserTicket

*@returnJSONObject*/

publicJSONObject getUserDetail(String accessToken,UserTicket userTicket) {//1.获取请求地址

String get_userDetail_url=GET_USERDETAIL_URL.replace("ACCESS_TOKEN", accessToken);//2.准备好请求包体

Gson gson = newGson();

String jsonUserTicket=gson.toJson(userTicket); //使用gson.toJson(user)即可将user对象顺序转成json

System.out.println("jsonUserTicket:"+jsonUserTicket);//2.调用接口,发送请求,获取成员信息

JSONObject jsonObject = WeiXinUtil.httpRequest(get_userDetail_url, "POST", jsonUserTicket);

System.out.println("jsonObject:"+jsonObject.toString());//3.错误消息处理

if (null !=jsonObject) {if (0 != jsonObject.getInt("errcode")) {

log.error("获取成员信息失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));

}

}returnjsonObject;

}

}

View Code

2.4前端页面——MTAuthorization.jsp

授权成功后将跳转到这个页面。在这个页面里调用了MTAuthorizationService中的方法来获取用户信息

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

移动端网页授权

String state=request.getParameter("state");

MTAuthorizationService mts=newMTAuthorizationService();

String accessToken=WeiXinUtil.getAccessToken(WeiXinParamesUtil.corpId, WeiXinParamesUtil.agentSecret).getToken();//获取成员信息

JSONObject userInfo=mts.getUserInfo(accessToken, code);//获取成员详情

UserTicket userTicket=newUserTicket();

userTicket.setUser_ticket(userInfo.getString("user_ticket"));

JSONObject userDetail=mts.getUserDetail(accessToken, userTicket);%>hello,这里是第三方应用

code=
state=
userInfo=
userTicket=
userDetail=

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值