管理员身份登录企业微信管理后台 https://work.weixin.qq.com/wework_admin/frame#apps
创建企业微信应用
应用创建步骤和配置
- 查看企业ID》》》点击"我的企业",查看"企业ID",并记录【企业ID】
- 进入应用管理 创建自建应用 【Windseeker管理平台】(应用可见范围和其他选项可直接配置也可后续配置)
- 配置应用信息 其中需要记录【AgentId】 和 【Secret】 ,并按照手册编写应用主页的link( tips:可阅读文档:https://work.weixin.qq.com/api/doc/90000/90135/91022 )
- 添加自定义菜单(tips:如菜单需要访问主页 可直接使用上述的link)
- 设置可信域名 填写项目的域名
- 至此我们已经可以在手机或PC的企业微信中使用自建应用(示例如下)
- 将上述记录的【AgentId】 【Secret】【企业ID】 对【项目】进行配置或修改,使用户(项目用户绑定过企业微信)进入自建应用【Windseeker管理平台】能够实现自动登录(配置/修改实际的应用项目!!!) 具体步骤见下
编写工具类
WeChatUtil工具类中的【corpid】=上述的【企业ID】/【secret】=上述的【Secret】/【agentid】=上述的【AgentId】
- https://work.weixin.qq.com/api/doc/90000/90135/91039 (获取获取access_token)
- https://work.weixin.qq.com/api/doc/90000/90135/91023 (获取访问用户身份)
- https://work.weixin.qq.com/api/doc/90000/90135/90236 (发送应用消息)
AccessToken
/**
* AccessToken
* @Author Lehman
* @EmailInfo <280668200@qq.com>
* @Date 2020-09-28
*/
@Data
public class AccessToken {
/**
* 状态
*/
private String errcode;
/**
* 消息
*/
private String errmsg;
/**
* access_token
*/
private String access_token;
}
WeChat
/**
* WeChat
* @Author Lehman
* @EmailInfo <280668200@qq.com>
* @Date 2020-09-28
*/
@Data
public class WeChat {
/**
* 状态
*/
private String errcode;
/**
* 用户ID
*/
private String UserId;
/**
* DeviceId
*/
private String DeviceId;
}
WeChatData
/**
* 微信消息发送实体类
* @author Lehman
* @Date 2020-09-28
* @email 280668200@qq.com
*
*/
@Data
public class WeChatData {
/**
* 成员账号
*/
private String touser;
/**
* 消息类型
*/
private String msgtype;
/**
* 企业用用的agentid
*/
private String agentid;
/**
* 十几接收map类型数据
*/
private Object text;
/**
* 状态
*/
private String errcode;
}
WeChatUtil工具类
package com.windseeker.common.system.utlis;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.Gson;
import com.windseeker.common.core.utils.HttpsUtils;
import com.windseeker.common.system.entity.AccessToken;
import com.windseeker.common.system.entity.WeChat;
import com.windseeker.common.system.entity.WeChatData;
import org.apache.http.client.ClientProtocolException;
import com.alibaba.fastjson.JSONArray;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.stereotype.Component;
/**
* 微信工具类
* @author Lehman
* @Date 2020-09-28
* @email 280668200@qq.com
*
*/
@Configuration
public class WeChatUtil {
private static String WX_corpid;
private static String WX_Secret;
private static String WX_AGENTID;
public String getWX_corpid() {
return WX_corpid;
}
@Value("${wx.corpid}")
public void setWX_corpid(String WX_corpid) {
this.WX_corpid = WX_corpid;
}
public String getWX_Secret() {
return WX_Secret;
}
@Value("${wx.secret}")
public void setWX_Secret(String WX_Secret) {
this.WX_Secret = WX_Secret;
}
public String getWX_AGENTID() {
return WX_AGENTID;
}
@Value("${wx.agentid}")
public void setWX_AGENTID(String WX_AGENTID) {
this.WX_AGENTID = WX_AGENTID;
}
/**
* 获取 AccessToken
* @return
*/
public static AccessToken getToken(){
/*获取AccessToken*/
String access_token="";
try {
access_token = HttpsUtils.sendSSL("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid="+WX_corpid+"&corpsecret="+WX_Secret);
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
AccessToken accessToken=JSONArray.parseObject(access_token, AccessToken.class);
return accessToken;
}
/**
* 获取当前登录的企业微信用户
* @param token
* @param code
* @return
*/
public static WeChat getUser(String token, String code){
String user="";
try {
user = HttpsUtils.sendSSL("https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo?access_token="+token+"&code="+code);
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WeChat weChat=JSONArray.parseObject(user, WeChat.class);
return weChat;
}
/**
* 推送消息
* @return
* wc.getErrcode().equals("0") OK
* wc.getErrcode().equals("40008") renderError("Error code:40008---企业微信接口异常,参数错误或格式错误!");
* wc.getErrcode().equals("40003") renderError("Error code:40003---企业微信接口异常,无效的UserID!");
* else renderError("Error code:280500---企业微信接口异常!");
*/
public static WeChatData sendMessage(String token, String userId, String contentMsg){
//String msgtype="mytext";
String agentid=WX_AGENTID;//WxConstants.AGENTID是应用的agenid
WeChatData wcd = new WeChatData();
wcd.setTouser(userId);
wcd.setAgentid(agentid);
wcd.setMsgtype("text");
Map<Object, Object> content = new HashMap<Object, Object>();
content.put("content", contentMsg);
wcd.setText(content);
Gson gson=new Gson();
String msg="";
try {
msg = HttpsUtils.sendPostSSL("https://qyapi.weixin.qq.com/cgi-bin/message/send?debug=1&access_token=" + token, gson.toJson(wcd));
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
WeChatData wc=JSONArray.parseObject(msg, WeChatData.class);
return wc;
}
}
自建应用实现自动授权登录
根据上述自建应用我们构造链接跳转后可以在地址栏获取到【CODE】(详情见:https://work.weixin.qq.com/api/doc/90000/90135/91022 )
根据前面的工具类和【AgentId】 【Secret】【企业ID】【CODE】可以自定义编写业务需求,最终实现前端/后端互通(此处根据自己业务实现,此处不在赘述)
基础思路如下:
前端处理
//企业微信自动登录
$.ajax({
url: requestUrl+'login',
type: 'POST',
data:{code:code}, // code 在地址栏获取 code只能使用一次,5分钟未被使用自动过期。
success: function (res,status,xhr) {
if (0 === res.code) {
layer.msg('登录成功', {icon: 1, time: 1000, shade: [0.3,'#000']})
} else {
layer.msg(res.msg || '登录失败', {icon: 2, anim: 6})
}
},error:function (e) {
layer.msg(`企业微信自动登录接口异常`)
return;
}
});
后端处理
String code=request.getParameter("code");
if(StringUtil.isNotBlank(code)){
WeChat weChat= WeChatUtil.getUser(WeChatUtil.getToken().getAccess_token(),code);
if(weChat.getErrcode().equals("0")) {
// .... 此处根据业务需求编写代码 其中【weChat.getUserId()】为用户企业微信标识!!!
if (【登录业务返回结果】)
return JsonResult.ok("登录成功!");
else
return JsonResult.error("自动登录失败,您的企业微信账户当前未与系统绑定,请使用账号密码登录!");
} else
return JsonResult.error("自动登录失败,企业微信接口异常 code无效!");
}else{
return JsonResult.error("自动登录失败,企业微信接口异常 cdoe为空!");
}
以下为设计和实现中需要注意的几点:
- 设计并编写用户绑定企业微信用户【项目】用户中记录【企业微信用户】标识,确保【项目用户】和【企业微信用户】的绑定(!!!如果【项目】直接使用企业微信用户 作为基础用户,可忽略)
- 前端获取到【CODE】及时传递给后端进行验证,【CODE】只能使用一次,5分钟未被使用自动过期。
web应用实现企业微信扫码登录
自建应用配置
步骤一:引入JS文件
在需要展示企业微信网页登录二维码的网站引入如下JS文件,(支持https):
http://rescdn.qqmail.com/node/ww/wwopenmng/js/sso/wwLogin-1.0.0.js
步骤二:在需要使用微信登录的地方实例以下JS对象
window.WwLogin({
"id" : "wx_reg", // 显示二维码的容器ID
"appid" : "", // 企业微信的【企业ID】
"agentid" : "", // 自建应用的【AgentId】
"redirect_uri" :"回调的URL/loginWeChat(自定义接口)", // 【重定向地址】,需要进行UrlEncode
"state" : "", // 用于保持请求和回调的状态,授权请求后原样带回给企业。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议企业带上该参数,可设置为简单的随机数加session进行校验()
"href" : "", // 自定义样式链接,企业可根据实际需求覆盖默认样式(具体详情见企业微信文档)(非必填)
});
用户允许授权后,将会重定向到redirect_uri的网址上,并且带上【code】和【state】参数
步骤三:编写【重定向地址】接口
上述重定向到接口后,地址会带上【code】和【state】参数,我们根据【code】和【state】参数以及上述的【WeChatUtil】编写业务代码 实现扫码登录(此处根据自己业务实现,此处不在赘述)
web应用实现推送消息到企业微信
基础消息推送直接调用上述【WeChatUtil】的【sendMessage】函数(具体业务需求请根据实际业务编写代码,此处不在赘述)
开发使用文档
具体业务实现请结合企业微信文档https://work.weixin.qq.com/api/doc/90000/90135/90664