i更新
This commit is contained in:
@@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
// | 企业微信客服桌面端管理员认证接口
|
||||||
|
// +----------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace app\adminapi\controller;
|
||||||
|
|
||||||
|
use app\common\enum\AdminTerminalEnum;
|
||||||
|
use app\common\enum\YesNoEnum;
|
||||||
|
use app\common\model\auth\Admin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用最小身份信息把 ZYT 管理员账号映射到客服软件租户。
|
||||||
|
*
|
||||||
|
* session 标为免登录是为了跳过管理后台的菜单权限和登录 IP 限制;它并非匿名
|
||||||
|
* 接口,方法内部仍会严格校验 token 以及 token 的桌面终端类型。客服后台从另一
|
||||||
|
* 台服务器验证 token 时,请求 IP 本来就不会等于桌面用户登录时的 IP。
|
||||||
|
*/
|
||||||
|
class DesktopController extends BaseAdminController
|
||||||
|
{
|
||||||
|
public array $notNeedLogin = ['session'];
|
||||||
|
|
||||||
|
public function session()
|
||||||
|
{
|
||||||
|
$identity = (array)($this->request->adminInfo ?? []);
|
||||||
|
if (empty($identity) || empty($identity['admin_id'])) {
|
||||||
|
return $this->fail('登录已失效,请重新登录');
|
||||||
|
}
|
||||||
|
if ((int)($identity['terminal'] ?? 0) !== AdminTerminalEnum::WECOM_RPA) {
|
||||||
|
return $this->fail('当前登录令牌不属于企业微信客服桌面端');
|
||||||
|
}
|
||||||
|
|
||||||
|
$admin = Admin::where(['id' => (int)$identity['admin_id']])
|
||||||
|
->field('id,account,name,avatar,disable')
|
||||||
|
->findOrEmpty();
|
||||||
|
if ($admin->isEmpty() || (int)$admin['disable'] === YesNoEnum::YES) {
|
||||||
|
return $this->fail('管理员不存在或已禁用');
|
||||||
|
}
|
||||||
|
|
||||||
|
$account = trim((string)$admin['account']);
|
||||||
|
$name = trim((string)$admin['name']);
|
||||||
|
return $this->data([
|
||||||
|
// 加类型前缀,避免管理员 id 与普通用户 id 相同时落到同一个客服租户。
|
||||||
|
'user_id' => 'admin:' . (int)$admin['id'],
|
||||||
|
'sn' => $account,
|
||||||
|
'nickname' => $name !== '' ? $name : $account,
|
||||||
|
'mobile' => '',
|
||||||
|
'avatar' => (string)$admin['avatar'],
|
||||||
|
'terminal' => AdminTerminalEnum::WECOM_RPA,
|
||||||
|
'expire_time' => (int)($identity['expire_time'] ?? 0),
|
||||||
|
'status' => 'active',
|
||||||
|
'account_type' => 'admin',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,8 @@ use think\facade\Log;
|
|||||||
class LoginValidate extends BaseValidate
|
class LoginValidate extends BaseValidate
|
||||||
{
|
{
|
||||||
protected $rule = [
|
protected $rule = [
|
||||||
'terminal' => 'require|in:' . AdminTerminalEnum::PC . ',' . AdminTerminalEnum::MOBILE,
|
'terminal' => 'require|in:' . AdminTerminalEnum::PC . ',' . AdminTerminalEnum::MOBILE
|
||||||
|
. ',' . AdminTerminalEnum::WECOM_RPA,
|
||||||
'account' => 'require',
|
'account' => 'require',
|
||||||
'password' => 'require|password',
|
'password' => 'require|password',
|
||||||
];
|
];
|
||||||
@@ -143,4 +144,4 @@ class LoginValidate extends BaseValidate
|
|||||||
return in_array($flag, ['1', 'true', 'yes', 'on'], true);
|
return in_array($flag, ['1', 'true', 'yes', 'on'], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,6 @@ class AdminTerminalEnum
|
|||||||
{
|
{
|
||||||
const PC = 1;
|
const PC = 1;
|
||||||
const MOBILE = 2;
|
const MOBILE = 2;
|
||||||
}
|
// 企业微信客服桌面软件。与网页端分开保存会话,桌面登录不会顶掉浏览器登录。
|
||||||
|
const WECOM_RPA = 7;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
use app\common\enum\AdminTerminalEnum;
|
||||||
|
|
||||||
|
function adminDesktopExpect(bool $condition, string $message): void
|
||||||
|
{
|
||||||
|
if (!$condition) {
|
||||||
|
fwrite(STDERR, "FAIL: {$message}\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adminDesktopExpect(AdminTerminalEnum::WECOM_RPA === 7, 'desktop admin terminal remains 7');
|
||||||
|
|
||||||
|
$validator = file_get_contents(dirname(__DIR__) . '/app/adminapi/validate/LoginValidate.php');
|
||||||
|
$controller = file_get_contents(dirname(__DIR__) . '/app/adminapi/controller/DesktopController.php');
|
||||||
|
adminDesktopExpect(is_string($validator) && is_string($controller), 'desktop auth sources are readable');
|
||||||
|
adminDesktopExpect(
|
||||||
|
str_contains($validator, 'AdminTerminalEnum::WECOM_RPA'),
|
||||||
|
'admin login accepts the dedicated desktop terminal'
|
||||||
|
);
|
||||||
|
adminDesktopExpect(
|
||||||
|
str_contains($controller, "public array \$notNeedLogin = ['session'];")
|
||||||
|
&& str_contains($controller, "'user_id' => 'admin:'")
|
||||||
|
&& str_contains($controller, "'account_type' => 'admin'"),
|
||||||
|
'desktop session verifies an admin token and namespaces its tenant identity'
|
||||||
|
);
|
||||||
|
|
||||||
|
echo "OK\n";
|
||||||
Reference in New Issue
Block a user