新版数智员工
This commit is contained in:
114
application/common/controller/OpenAuthController.php
Normal file
114
application/common/controller/OpenAuthController.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\facade\Log;
|
||||
use app\common\service\UserApiKeyService;
|
||||
use app\common\util\JwtUtil;
|
||||
|
||||
/**
|
||||
* 对外开放接口 — 鉴权控制器
|
||||
*
|
||||
* 第三方系统先用 apiKey + sign 换取 JWT Token,
|
||||
* 后续所有 /v1/open/* 业务接口只需在 Header 中携带:
|
||||
* Authorization: Bearer <token>
|
||||
* 即可调用,与存客宝内部接口完全兼容。
|
||||
*/
|
||||
class OpenAuthController extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取 JWT Token
|
||||
* POST /v1/open/auth/token
|
||||
*
|
||||
* 请求参数:
|
||||
* apiKey - 账号专属 API Key(ck_users.apiKey)
|
||||
* account - 登录账号(ck_users.account),参与签名
|
||||
* timestamp - 秒级时间戳
|
||||
* sign - 签名值,算法见签名文档
|
||||
*
|
||||
* 成功响应:
|
||||
* { code: 200, message: "success", data: { token: "xxx", expires_in: 7200 } }
|
||||
*/
|
||||
public function getToken()
|
||||
{
|
||||
try {
|
||||
$params = $this->request->param();
|
||||
|
||||
// ── 1. 必填参数校验 ─────────────────────────────────────────
|
||||
if (empty($params['apiKey'])) {
|
||||
return $this->fail('apiKey不能为空', 400);
|
||||
}
|
||||
if (empty($params['account'])) {
|
||||
return $this->fail('account不能为空', 400);
|
||||
}
|
||||
if (empty($params['sign'])) {
|
||||
return $this->fail('sign不能为空', 400);
|
||||
}
|
||||
if (empty($params['timestamp'])) {
|
||||
return $this->fail('timestamp不能为空', 400);
|
||||
}
|
||||
|
||||
// ── 2. 时间戳时效校验(±5 分钟)──────────────────────────────
|
||||
if (abs(time() - intval($params['timestamp'])) > 300) {
|
||||
return $this->fail('请求已过期', 400);
|
||||
}
|
||||
|
||||
// ── 3. 用 apiKey 找账号,并校验 account 一致性 ───────────────
|
||||
$user = UserApiKeyService::findUserByKey($params['apiKey']);
|
||||
if (!$user) {
|
||||
return $this->fail('无效的apiKey', 401);
|
||||
}
|
||||
if ($user['account'] !== $params['account']) {
|
||||
return $this->fail('无效的apiKey', 401);
|
||||
}
|
||||
|
||||
// ── 4. 验签(account + timestamp + apiKey)────────────────────
|
||||
if (!UserApiKeyService::validateSign(
|
||||
$params['account'],
|
||||
(string)$params['timestamp'],
|
||||
$params['apiKey'],
|
||||
$params['sign']
|
||||
)) {
|
||||
return $this->fail('签名验证失败', 401);
|
||||
}
|
||||
|
||||
// ── 5. 签发 JWT(2 小时有效期)────────────────────────────────
|
||||
$expireSeconds = 7200;
|
||||
$token = JwtUtil::createToken([
|
||||
'id' => (int)$user['id'],
|
||||
'account' => $user['account'] ?? '',
|
||||
'username' => $user['username'] ?? '',
|
||||
'phone' => $user['phone'] ?? '',
|
||||
'companyId' => (int)$user['companyId'],
|
||||
'typeId' => (int)$user['typeId'],
|
||||
'isAdmin' => (int)($user['isAdmin'] ?? 0),
|
||||
'via' => 'open_api', // 标记来源,方便日志区分
|
||||
], $expireSeconds);
|
||||
|
||||
Log::info('[OpenAuth] 对外接口登录成功', [
|
||||
'userId' => $user['id'],
|
||||
'account' => $user['account'],
|
||||
'ip' => $this->request->ip(),
|
||||
]);
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'message' => 'success',
|
||||
'data' => [
|
||||
'token' => $token,
|
||||
'expires_in' => $expireSeconds,
|
||||
],
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('[OpenAuth] getToken 异常:' . $e->getMessage());
|
||||
return $this->fail('系统错误: ' . $e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function fail(string $message, int $code = 400)
|
||||
{
|
||||
return json(['code' => $code, 'message' => $message, 'data' => null]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user