企业内部应用
企业微信提供了通讯录管理、客户联系、身份验证、应用管理、消息推送、素材管理、OA、效率工具、企业支付、企业互联、会话内容存档、电子发票、家校沟通、家校应用、政民沟通等API,企业可以使用这些API,为企业接入更多个性化的办公应用
身份验证
网页授权登录
OAuth的授权登录方式
从企业微信终端打开的网页可获取成员的身份信息,从而免去登录的环节
企业应用中的URL链接(包括自定义菜单或者消息中的链接),均可通过OAuth2.0验证接口来获取成员的UserId身份信息
OAuth2
允许用户在不告知第三方自己的账号密码情况下,通过授权方式,让第三方服务可以获取自己的资源信息。RFC 6749
Authorization Code模式
流程如下
包含四个角色
- ResourceOwner为资源所有者,即为用户
- User-Agent为浏览器
- AuthorizationServer为认证服务器,可以理解为用户资源托管方,比如企业微信服务端
- Client为第三方服务,比如企业自建应用
调用流程为:
A) 用户访问第三方服务,第三方服务通过构造OAuth2链接(参数包括当前第三方服务的身份ID,以及重定向URI),将用户引导到认证服务器的授权页
用户访问企业的自建应用时,设置的入口链接如果是 授权链接,则可以引导到企微认证服务器授权页
B) 用户选择是否同意授权
若选择默认方式,可以不弹出授权页面,直接重定向到 redirection_uri
C) 若用户同意授权,则认证服务器将用户重定向到第一步指定的重定向URI,同时附上一个授权码。
如果可信域名和授权链接 redirection_uri 写的本机,会访问到本地,可以看到 code
D) 第三方服务收到授权码,带上授权码来源的重定向URI,向认证服务器申请凭证。
获取的 access_token 可以关联到重定向URI
E) 认证服务器检查授权码和重定向URI的有效性,通过后颁发AccessToken(调用凭证)
D)与E)的调用为后台调用,不通过浏览器进行
企微OAuth2流程图
网页授权的可信域名
REDIRECT_URL中的域名,需要先配置为应用的“可信域名”,否则跳转时会提示“redirect_uri参数错误”
配置的可信域名,必须与访问链接的域名完全一致;若访问链接URL带了端口号,端口号也需要登记到可信域名中
假定重定向访问的链接是:http://mail.qq.com:8080/cgi-bin/helloworld
则可信域名需要配置为 mail.qq.com:8080
静默授权与手动授权
静默授权:用户点击链接后,页面直接302跳转至 redirect_uri?code=CODE&state=STATE
手动授权:用户点击链接后,会弹出一个中间页,让用户选择是否授权,用户确认授权后再302跳转至 redirect_uri?code=CODE&state=STATE
个人敏感信息授权管理
- 用户首次进入oauth2页面进行手动授权后,30天内再次进入应用页面不会再弹出授权页,默认授权用户当前授权的敏感信息。若30天内用户需要修改个人敏感信息授权,可进入应用详情页的“个人敏感信息授权管理”页面,重新更改个人敏感信息授权
缓存方案建议
通过OAuth2.0验证接口获取成员身份会有一定的时间开销。对于频繁获取成员身份的场景,建议采用如下方案:
企业应用中的URL链接直接填写企业自己的页面地址
即授权链接的url http://open.weixin.qq.com/connect/oauth2/authorize? 填写自己的页面地址,自己判断是否去企微重新获取
成员操作跳转到步骤1的企业页面时,企业后台校验是否有标识成员身份的cookie信息,此cookie由企业生成
如果没有匹配的cookie,则重定向到OAuth验证链接,获取成员的身份信息后,由企业后台植入标识成员身份的cookie信息
根据cookie获取成员身份后,再进入相应的页面
服务端API业务流程
获取 access_token
调用企微API接口的第一步,需要通过 access_token 来鉴权调用者身份
不同的业务API可能需要不同来源的 access_token,需要明确 access_token 的来源
每个应用有独立的secret,获取到的access_token只能本应用使用,进行缓存时需要区分应用来进行存储
access_token至少保留512字节的存储空间。
不能频繁调用gettoken接口,否则会受到频率拦截。当access_token失效或过期时,需要重新获取。
access_token的有效期通过返回的expires_in来传达,正常情况下为7200秒(2小时),有效期内重复获取返回相同结果,过期后获取会返回新的access_token。
企业微信可能会出于运营需要,提前使access_token失效,开发者应实现access_token失效时重新获取的逻辑
不能将 access_token 返回给前端,需要保存在后台,所有访问企业微信api的请求由后台发起
1 | async getOrRefreshToken(params: { |
同步组织架构
后端程序启动时需要先通过 access_token 获取一遍组织架构信息
企业自建应用 不受 通讯录管理的 安全机制限制
只有通讯录同步助手(一种应用类型)才受安全机制限制
获取子部门ID列表
不填部门id,获取全量组织架构
获取部门成员详情
- 根据获取的部门ID获取该部门的成员信息
- 只能获取应用配置的可见范围内的成员信息
- 不递归获取子部门的成员
判断是不是当前部门的leader
1 | userInfo['is_leader_in_dept'][userInfo['department'].findIndex((e) => e === depId)] === 1 ? 'true' : 'false' |
本地保存
将组织架构信息保存到本地
获取访问用户身份
根据 code 获取成员信息
code 通过构造网页授权链接获取
参数
code
通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期
业务逻辑
获取到用户 userid 后,通过同步到本地的组织架构信息,查询该 userid 的信息,例如自己配置的用户角色等
返回 token,作为前端后续调用自己后端服务的凭证
将获取到的 userid 信息,作为返回 token 的 payload,包括 userid,role等
成员管理
读取成员
没有入职及离职时间,可在创建成员时通过新增扩展字段-入职时间来设置
消息推送
发送应用消息
打卡、审批等操作,在自己的后端处理完业务逻辑之后,可以向企微用户发送通知消息
文本消息
文本卡片消息
按钮交互型
需要提前配置回调地址
如果报错 43012,则需要配置
注意 nginx转发路由也要拼接
企业管理后台配置
通讯录secret
在 安全与管理-> 管理工具 -> 通讯录同步->
开启接口同步
查看 secret
配置可信IP
后端的外网ip地址
应用管理
自建应用
创建应用后可以看到 AgentId、Secret
这个 secret 是应用的secret,获取 access_token
可见范围
- 用来添加组织架构
通过 access_token 同步该组织架构中的成员
应用主页
设置从工作台点击进入的网页
如果要获取 code,则需要构建一个 网页授权链接
1
2
3
4
5
6http://open.weixin.qq.com/connect/oauth2/authorize?
appid=ww970b9d959208f458&
redirect_uri=https://www.dawei.cn:12345&
response_type=code&
scope=snsapi_base&
state=%7B%22school_id%22%3A%22school_qiwei%22%7D#wechat_redirect其中 redirect_uri(IP+Port)需要配置为可信域名
接收消息
如果要发送应用消息中的模板卡片消息,则需要配置一个回调地址
url 配置为后端入口
token、EncodingAESKey 自动生成,用于校验收到的信息
node 用腾讯的 @wecom/crypto
1
2
3
4
5
6
7
8
9
10
11
12import { getSignature, decrypt } from '@wecom/crypto'
async handleGetCallback(query: GetCallbackDto) {
const { msg_signature, timestamp, nonce, echostr } = query;
const sign = getSignature(Conf.qiwei.callbackToken, timestamp, nonce, echostr)
if (sign !== msg_signature) {
throw Error('illegal msg')
}
const { message } = decrypt(Conf.qiwei.callbackEncoding, echostr)
return message.trim()
}
// 注意如果框架有统一的返回格式,返回结果需要特殊处理,只能返回解密后的message字符串如果出现 openapi 回调地址不通过,可通过工具 建立连接->测试回调模式 来查看返回的结果是不是正确的
企业可信IP
需要把后端服务的外网IP加入
如果不知道外网ip,直接调用接口,报错信息会给出当前网络的外网ip
网页授权及JS-SDK
可信域名
需要配置为OAuth2.0网页授权功能的回调域名
不能包含协议头,不支持IP地址及短链域名
配置完需要验证,下载一个文件,放到根目录
如果后端有http服务,例如 nest,可以将文件放在服务器的静态目录
public
下,这样企微可以通过配置的可信域名访问到本地的文件,就可以验证通过1
2
3
4
5
6
7// 配置静态资源
app.useStaticAssets(join(__dirname, '../public'), {
prefix: '/',
setHeaders: res => {
res.set('Cache-Control', 'max-age=2592000')
}
});
后端自己测试
将可信域名配置为后端的地址 www.dawei.cn:12345,将验证文件放在项目的静态目录下,完成验证。
这里需要 https监听的端口
授权链接中的 redict_url 设为后端地址 www.dawei.cn:12345
在企微客户端的用户窗口,发送
网页授权链接
,点击链接,企微就会访问到后端,拿到带有 code 的信息,再用code去 获取访问用户身份1
::ffff:172.18.228.110 "GET /?code=_k2rDYZzyNMvcdxxOsEEBOoDFmMjpPIljQEVD13Q&state=%7B%22school_id%22%3A%22school_qiwei%22%7D" undefined Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 wxwork/4.1.20 MicroMessenger/7.0.1 Language/zh ColorScheme/Light undefined
生产环境,前端在进入应用的时候会携带code