第一次对接企业微信,上网找了各种方案。
目的是在企业微信中,公司发给员工一个地址,员工点开后打开画面,在这个画面上可以获取到这个员工的userid(后续功能操作就是各自不同的功能了哈,就不详细说了)。
然后根据官网内容,分析了一下,我需要连接官网的【构造网页授权】【获取token】【获取用户信息】。
然后调查了别人怎么写,查来查去除了写内容,还需要一些配置。
前端使用的vue的uniapp框架。后台使用Java。
如果符合你现在的需求,可以参照下面的方法~ ^-^~
1. 企业微信相关官网
先了解企业微信官网介绍 获取access_token - 接口文档 - 企业微信开发者中心
【构造网页授权】【获取token】【获取用户信息】部分的接口介绍。
2. 企业微信创建应用,我参照的是以下文章
http://t.csdn.cn/hUAXz
3. 前端代码
onLoad() {this.getwecom();},methods: {getwecom() {// 当前企业的 corp_idconst corp_id = 'xxxxxxxxxxx企业的corp_id';// 重定向 URL → 最终打开的画面地址,域名是在企业微信上配置好的域名 比如我的域名是https://my.test.com:9999/#/ → #是代表路径结束。这里/和#必须这样子写。const redirect_uri = encodeURI('https://my.test.com:9999/#/');//企业的agentId 每个应用都不一样const agentId = 10000001;//获取当前路径的code(有code代表已经回调过了)let code = this.getUrlCode(); //是否存在codeif(code === undefined || code == null || code === "") {//不存在就打开地址进行授权,这里是默认授权(没写手动授权咋写),授权后直接跳转到redirect_uri 设置的地址,地址后会有回调的code参数值//必须是encodeURIComponent(路径)window.location.href =`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${corp_id}&redirect_uri=${encodeURIComponent(redirect_uri)}&response_type=code&scope=snsapi_base&state=STATE&agentid=${agentId}#wechat_redirect`}//到这里已经是能获取到code了(已经经过了企业微信授权)//获取token和用户信息可以在后台调用,weComAuthorize就是当前框架访问后台的方法。和后台项目配置的返回值。具体企业微信返回内容请参照官网。weComAuthorize(code).then(res => {if (res.code == 200 && res.user.errcode == 0) {console.log(res.user.userid)alert(res.user.userid)}})},getUrlCode() {// 截取url中的code方法let url = new URL(window.location.href)return new URLSearchParams(url.search).get("code");},
}
4.后台代码
import net.sf.json.JSONObject;/*** 前台网页授权后 - 获取企业微信的token 根据token和code得到用户信息** @return 结果*/public AjaxResult getUserInfo(HttpServletRequest request, @PathVariable("code") String code) throws Exception{// 获取token 这里获取token的方案本案例就不详细贴附了,可以参照获取用户信息方式去获取token//corpId等参数值,需要在企业微信查到,传入WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();config.setCorpId(corpId);config.setCorpSecret(corpSecret);config.setAgentId(agentId);WxCpServiceImpl wxCpService = new WxCpServiceImpl();wxCpService.setWxCpConfigStorage(config);WxCpExternalServiceImpl wxCpExternalService = new WxCpExternalServiceImpl(wxCpService);String token = wxCpExternalService.getToken();//根据code获取用户信息,url地址拼接参照官网地址String url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token="+token+"&code="+code;JSONObject jsonObject = HttpsRequestUtil.httpsRequest(url, "GET", null);System.out.println(jsonObject);AjaxResult ajax = AjaxResult.success();ajax.put("user", jsonObject);return ajax;}
//发送请求的工具类
package com.xxx.xxxx.util;import net.sf.json.JSONObject;import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.URL;public class HttpsRequestUtil {/*** 发起https请求并获取结果** @param requestUrl 请求地址* @param requestMethod 请求方式(GET、POST)* @param outputStr 提交的数据* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)*/public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {JSONObject jsonObject = null;HttpsURLConnection conn = null;try {// 创建SSLContext对象,并使用我们指定的信任管理器初始化TrustManager[] tm = { new MyX509TrustManager() };SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");sslContext.init(null, tm, new java.security.SecureRandom());// 从上述SSLContext对象中得到SSLSocketFactory对象SSLSocketFactory ssf = sslContext.getSocketFactory();URL url = new URL(requestUrl);conn = (HttpsURLConnection) url.openConnection();conn.setSSLSocketFactory(ssf);conn.setDoOutput(true);conn.setDoInput(true);conn.setUseCaches(false);conn.setConnectTimeout(5000);// 设置请求方式(GET/POST)conn.setRequestMethod(requestMethod);// 当有数据需要提交时if (null != outputStr) {OutputStream outputStream = conn.getOutputStream();// 注意编码格式,防止中文乱码outputStream.write(outputStr.getBytes("UTF-8"));outputStream.close();}// 将返回的输入流转换成字符串InputStream inputStream = conn.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");BufferedReader bufferedReader = new BufferedReader(inputStreamReader);String str = null;StringBuffer buffer = new StringBuffer();while ((str = bufferedReader.readLine()) != null) {buffer.append(str);}jsonObject = JSONObject.fromObject(buffer.toString());// 释放资源bufferedReader.close();inputStreamReader.close();inputStream.close();} catch (ConnectException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {if (conn != null) {conn.disconnect();}}return jsonObject;}}
注意:
① https://my.test.com:9999/#/这个域名需要加在企业微信的受信任域名里,配置可以官网找参考
② 本地运行的的时候,需要把当前的公网ip配置在企业微信的应用的白名单ip设置里,配置可以百度参考。不加有可能报ip的错误。
③ 我当前本地没有办法实时运行,我都是改一点发布在环境里去看的。(如果有小可爱知道怎么在本地打开,麻烦留言给我哦)。
④ 如果改一点发布实在麻烦,可以分段代码测试,只要下列过程中,复制后的路径中有code,调用后台的方法返回的是40029错误,就发布到环境上试试对不对就行了。
下载一个pc端的企业微信,可以在HBuilder中,点击运行-运行到浏览器-选择一个浏览器运行,会得到这个画面
把图片中的路径,复制到企业微信里,在企业微信里点击。能跳转到你最终要的画面就证明没问题了。
打开之后点击右上角三个点点击复制链接地址。这个地址就是你最终要显示的画面地址啦~(ps:就是配置的redirect_uri 的值,如果这个时候地址打开的不是你想要的,可能就是前台这里的地址配置有问题!)
以下是复制后的地址
https://my.test.com:9999?code=CT0Io7SIbcgTTdHYZgYBHcBZe4N8hyBjlQawZRYy7lk&state=STATE#/
⑤ 前端要发布在当前域名的环境中,后台代码要是只在本地的话,需要把本地ip配置在当前域名下,不然打开④的画面是404找不到页面。
⑥ weComAuthorize调用后台的时候,可以在回调④中回调地址中复制code的参数,单独传给后台,测试后台返回的接口内容。如果后台返回的是【{"errcode":40029,"errmsg":"invalid code, hint: [1687329093612132300786691], from ip: 59.xx.xxx.130, more info at https://open.work.weixin.qq.com/devtool/query?e=40029"}】,那其实基本是没问题了。是code已经被使用,只要把前台的代码发布在环境里,在企业微信点击域名,就是能够得到用户id了。