前言
北森HR系统,比较流行的一个人力资源管理系统,很多公司都在使用,最近在做一个系统对接需求的时候,总结了一些方法,故记录一下过程并分享。
以下内容,个人浅见,如有巧合,以你为准
一、背景和需求
背景:公司使用北森HR系统作为人员信息管理系统,内部自研系统需对接北森获取北森HR系统人员信息,完成人员信息同步,实现自动入职开通内部系统账号、离职自动删除内部系统账号、调岗自动取消权限、同步组织架构等功能。
需求场景:内部系统同步北森HR系统人员、组织等信息,满足更高效、安全的内部系统账号管理需求。
二、实现思路
整体思路:使用北森的事件订阅器、OpenAPI连接器实现事件通知、同步内部系统信息,内部系统获取到回调信息后,自行开发相关逻辑实现人员账号信息同步
2.1 名词定义
名称 | 描述 |
---|---|
北森OpenAPI | 北森系统提供的 API 接口,开发者可以通过该接口获取信息 |
森事件订阅器 | 当事件(人事变动)发生时,平台会向开发者配置的URL推送已订阅事件的消息 |
自研系统(用户中心) | 订阅北森事件,拉取北森数据的统一入口,使用中心系统可减少北森 API 调用量的消耗 |
第三方系统 | 内部使用的第三方采购的系统 如飞书、企微、钉钉等 |
自建系统 | 内部使用的自建系统,如 LDAP、JumpServer、Gitlab等 |
2.2 开发流程图
2.3 流程说明
- 使用北森事件订阅器以"推"的方式推送信息,使用北森OpenAPI以"拉"的方式调取数据,使用"推"、"拉"两种方式结合完成信息同步;
- 事件订阅器能实现实时信息推送,理论上已能满足多数组织/人员同步需求场景,但根据官方的建议,推送有一定失败率,故建议增加补偿方案,即通过OpenAPI接口主动获取数据进行比对;
企业人员多的情况下,拉取全量数据的方式消耗是比较大的,据了解北森有限制调用量,超量呢。。。加钱,所以拉取数据的逻辑及周期就有讲究,这里不细说
三、开发步骤
3.1 北森管理者后台配置
3.1.1 创建OpenAPI连接器
3.1.2 获取连接器Key&Secret、绑定接口
3.1.3 创建事件订阅器
3.1.4 配置订阅器(需验证)
3.2 内部系统开发(PHP为例)
3.2.1 实现订阅器验证
根据官方方法实现验证信息的加解密,最终实现验证,验证完成后,方可完成订阅器的创建;
因为以前学废了,所以这里以PHP语言为例,目前官方文档仅提供C#/JAVA的加解密库,其他语言需自行实现;也等于是分享了一种方法,PHP的可以参考本文。
加解密库目录说明
- receiver.php 示例代码
- callback_json
- BSBizMsgCrypt.php 北森回调消息加解密接口
- errorCode.php 错误代码说明
- jsonparse.php 提供提取消息格式中的密文及生成回复消息格式的接口
- pkcs7Encoder.php 提供基于PKCS7算法的加解密接口
- sha1.php 计算北森的消息签名接口
PHP的加解密库参考代码见文末
3.2.2 PHP方法示例代码
<?php
/*
receiver.php
*/
include_once "callback_json/BSBizMsgCrypt.php";
// 北森上事件订阅器设置的Key信息
$token = "";//订阅器的token
$encodingAesKey = "";//订阅器的key
$sReceiveId = "";//特殊场景使用,默认留空
$sMsgSig = $_GET['msg_signature'];//从接收消息的URL中获取的msg_signature参数
$sTimeStamp = $_GET['timestamp'];//从接收消息的URL中获取的timestamp参数
$sNonce = $_GET['nonce'];//从接收消息的URL中获取的nonce参数
$sEchoStr = $_GET['echostr'];//从接收消息的URL中获取的echostr参数。注意,此参数必须是urldecode后的值
$rEchoStr = "";//解密后的明文消息内容,用于回包。注意,必须原样返回,不要做加引号或其它处理
$bscpt = new BSBizMsgCrypt($token, $encodingAesKey, $sReceiveId);
/* 判断是否首次验证回调的场景,该场景请求会携带echostr,非首次场景不会携带该参数 */
if (!isset($sEchoStr) && !empty($sEchoStr)) {
$errCode = $bscpt->VerifyURL($sMsgSig, $sTimeStamp, $sNonce, $sEchoStr, $rEchoStr);
if ($errCode == 0) {
echo $rEchoStr;
} else {
print("ERR: " . $errCode . "\n\n");
}
}
/*获取application/json数据,接收并解析消息的body中获取的msg_encrypt数据 */
$sEncryptMsg = file_get_contents('php://input');
//var_dump($sEncryptMsg);
$sMsg = "";// 解析之后的明文
$errCode = $bscpt->DecryptMsg($sMsgSig, $sTimeStamp, $sNonce, $sEncryptMsg, $sMsg);
if ($errCode == 0) {
// 解密成功,sMsg即为xml格式的明文
print("done DecryptMsg, sMsg : \n");
var_dump($sMsg);
// TODO: 对明文的处理
} else {
print("ERR: " . $errCode . "\n\n");
//exit(-1);
}
3.2.3 通过事件订阅器推送的事件信息处理业务逻辑
//订阅器推送的信息示例
{"tenant_id":****,"biz_id":"dd9c0647-****-****-****-265d1bdec1a4","biz_type":1,"biz_typeCode":"EmpEvent","biz_data":"{\"tenantId\":****,\"userId\":\"406384671\",\"type\":\"AddEmp\"}"}
根据回调信息里的userId获取用户信息;再根据type处理后续事件逻辑,这里Type:AddEmp即为员工入职事件,可以同步推送到其他内部系统实现账号开通等逻辑;
官方接口:参考《根据员工UserID集合获取未删除的员工相关信息》
关于订阅事件推送的信息解释,也可以查看官方文档《北森事件订阅器员工事件》
3.3 OpenAPI入门使用方法
3.3.1 获取企业access_token
请求地址:https://openapi.italent.cn/token
请求方式:POST
Content-Type:application/json
- 请求结构
名称 | 类型 | 说明 | 是否必填 |
---|---|---|---|
grant_type | string | 授权类型:client_credentials(获取token场景,固定传值 client_credentials) | 是 |
app_key | string | Key | 是 |
app_secret | string | 申请应用时分配的Secret | 是 |
3.3.2 获取access_token示例
3.3.3 调用API的请求头信息
调用其他OpenAPI接口时在请求头Header里加上Authorization及Content-Type参数;
Authrization参数为 Bearer+token,
Content-Type参数为【application/json】
3.2.4 通过北森OpenAPI接口实现三方信息同步
参考官方文档《北森组织员工主数据同步三方OA》
四、写在最后
关于数据推送,补充一种可选方案:通过工作流触发器等实现事件推送;例:入职流程审批通过后,触发信息推送至内部系统;
缺点:这种方案对流程要求比较严格,适用于企业内所有信息都通过工作流录入的场景,需考虑人工干预等场景的补偿机制;
优点:该方案也可以满足一些特殊场景的使用需求,如需要在流程过程中进行处理的信息;例:离职人员资产交接场景,离职流程到达交接节点的时候(未完全审批完成),推送资产回收工单至企业内部资产管理系统;
参考文档:《北森工作流触发器》
五、相关文档
- 北森事件订阅器开发文档 https://bsurl.cn/e8KAl3Bt
- 北森组织员工主数据同步三方OA https://bsurl.cn/pzB5Dqzl
- 北森开发者平台 https://open.italent.cn/
- 北森事件订阅器-PHP加解密库 https://github.com/WannaCryZ/php_beisen_receiver