第一次对接企业微信,上网找了各种方案。
目的是在企业微信中,公司发给员工一个地址,员工点开后打开画面,在这个画面上可以获取到这个员工的userid(后续功能操作就是各自不同的功能了哈,就不详细说了)。
然后根据官网内容,分析了一下,我需要连接官网的【构造网页授权】【获取token】【获取用户信息】。
然后调查了别人怎么写,查来查去除了写内容,还需要一些配置。
前端使用的vue的uniapp框架。后台使用Java。
如果符合你现在的需求,可以参照下面的方法~ ^-^~
1. 企业微信相关官网
先了解企业微信官网介绍 获取access_token - 接口文档 - 企业微信开发者中心
【构造网页授权】【获取token】【获取用户信息】部分的接口介绍。
2. 企业微信创建应用,我参照的是以下文章
http://t.csdn.cn/hUAXz
3. 前端代码
onLoad() {
this.getwecom();
},
methods: {
getwecom() {
// 当前企业的 corp_id
const 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();
//是否存在code
if(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了。