65 lines
1.9 KiB
PHP
65 lines
1.9 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Middleware;
|
||
|
||
use Closure;
|
||
use App\Models\AdminUser;
|
||
use App\Lottery\ErrorCode;
|
||
use App\Support\ApiResponse;
|
||
use Illuminate\Http\Request;
|
||
use Laravel\Sanctum\PersonalAccessToken;
|
||
use Symfony\Component\HttpFoundation\Response;
|
||
|
||
/**
|
||
* 后台 API:`auth:sanctum` 之后执行,校验为 {@link AdminUser} 且未禁用;
|
||
* 上下文可通过 `$request->lotteryAdmin()` 读取。
|
||
*/
|
||
final class EnsureAdminApi
|
||
{
|
||
public function handle(Request $request, Closure $next): Response
|
||
{
|
||
$user = $request->user();
|
||
|
||
if (! $user instanceof AdminUser) {
|
||
return ApiResponse::error(
|
||
trans('admin.unauthenticated', [], $request->lotteryLocale()),
|
||
ErrorCode::AdminUnauthenticated->value,
|
||
null,
|
||
401,
|
||
);
|
||
}
|
||
|
||
if ((int) $user->status !== 0) {
|
||
return ApiResponse::error(
|
||
trans('admin.account_disabled', [], $request->lotteryLocale()),
|
||
ErrorCode::AdminAccountDisabled->value,
|
||
null,
|
||
403,
|
||
);
|
||
}
|
||
|
||
$accessToken = $user->currentAccessToken();
|
||
if (
|
||
(int) $user->admin_session_version > 0
|
||
&& $accessToken instanceof PersonalAccessToken
|
||
&& $accessToken->name === 'admin-api'
|
||
) {
|
||
$expectedAbility = 'admin-session:'.(int) $user->admin_session_version;
|
||
$abilities = is_array($accessToken->abilities) ? $accessToken->abilities : [];
|
||
|
||
if (! in_array($expectedAbility, $abilities, true)) {
|
||
return ApiResponse::error(
|
||
trans('admin.session_replaced', [], $request->lotteryLocale()),
|
||
ErrorCode::AdminSessionReplaced->value,
|
||
null,
|
||
401,
|
||
);
|
||
}
|
||
}
|
||
|
||
$request->attributes->set('lottery_admin', $user);
|
||
|
||
return $next($request);
|
||
}
|
||
}
|