fix(auth): fail closed on token and validation checks

Made-with: Cursor
This commit is contained in:
apple
2026-04-29 17:32:08 +08:00
parent d6b9d1d0e3
commit 7e9c5105bb
5 changed files with 31 additions and 6 deletions

View File

@@ -7,6 +7,7 @@ namespace app\common\controller;
use app\Request;
use think\App;
use think\exception\ValidateException;
use think\Response;
/**
@@ -73,6 +74,10 @@ abstract class AppBaseController
$validator->message($scene);
}
return $validator->check($data);
if (!$validator->check($data)) {
throw new ValidateException($validator->getError());
}
return true;
}
}

View File

@@ -32,10 +32,11 @@ class AccessTokenService
*
* @param callable $resolver 根据 token 内的 id 读取账号模型或数组
* @param callable $authHashResolver 根据账号返回当前有效的 auth hash
* @param callable|null $accountValidator 根据账号判断当前 token 是否仍可用
* @return mixed
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function parseToken(string $token, string $type, callable $resolver, callable $authHashResolver)
public function parseToken(string $token, string $type, callable $resolver, callable $authHashResolver, callable $accountValidator = null)
{
if (!$token || $token === 'undefined') {
throw new AuthException(ApiErrorCode::ERR_LOGIN);
@@ -78,6 +79,11 @@ class AccessTokenService
throw new AuthException(ApiErrorCode::ERR_LOGIN);
}
if ($accountValidator && !$accountValidator($account)) {
$this->clearToken($md5Token, $type);
throw new AuthException(ApiErrorCode::ERR_LOGIN_INVALID);
}
if ($auth !== $authHashResolver($account)) {
throw new AuthException(ApiErrorCode::ERR_LOGIN_INVALID);
}

View File

@@ -81,7 +81,8 @@ class LoginServices extends BaseServices
$token,
'kefu',
fn($id) => $this->dao->get($id),
fn($adminInfo) => md5($adminInfo->password)
fn($adminInfo) => md5($adminInfo->password),
fn($adminInfo) => $adminInfo->status && $adminInfo->account_status
);
return $adminInfo->hidden(['password', 'ip', 'status']);

View File

@@ -81,8 +81,9 @@ class OutAccountServices extends BaseServices
$adminInfo = $services->parseToken(
$token,
'out',
fn($id) => $this->dao->get($id),
fn($adminInfo) => md5($adminInfo->appsecret)
fn($id) => $this->dao->getOne(['id' => $id, 'is_del' => 0]),
fn($adminInfo) => md5($adminInfo->appsecret),
fn($adminInfo) => (int)$adminInfo->status !== 2
);
return $adminInfo->hidden(['appsecret', 'ip', 'status']);
@@ -177,7 +178,7 @@ class OutAccountServices extends BaseServices
CacheService::redisHandler('out')->delete($md5Token);
$token = $jwtAuth->createToken($id, $type);
$token = $jwtAuth->createToken($id, $type, ['auth' => md5($authInfo->appsecret)]);
$data['last_time'] = time();
$data['ip'] = request()->ip();
$this->dao->update($id, $data);