mirror of
https://gitee.com/ctexthuang/hyperf_rbac_framework_server_ctexthuang.git
synced 2025-12-25 17:07:49 +08:00
feat : admin aspect
This commit is contained in:
32
app/Middleware/Admin/AdminTokenMiddleware.php
Normal file
32
app/Middleware/Admin/AdminTokenMiddleware.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware\Admin;
|
||||
|
||||
use App\Constants\ResultCode;
|
||||
use App\Exception\ErrException;
|
||||
use App\Interface\JwtInterface;
|
||||
use App\Middleware\Token\AbstractTokenMiddleware;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use function Hyperf\Support\env;
|
||||
|
||||
final class AdminTokenMiddleware extends AbstractTokenMiddleware
|
||||
{
|
||||
public function getJwt(): JwtInterface
|
||||
{
|
||||
return $this->jwtFactory->get('admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UnencryptedToken $token
|
||||
* @return void
|
||||
*/
|
||||
public function checkIssuer(UnencryptedToken $token): void
|
||||
{
|
||||
$audience = $token->claims()->get(RegisteredClaims::ISSUER);
|
||||
|
||||
if ($audience !== env('APP_NAME') .'_admin') throw new ErrException('token错误',ResultCode::JWT_ERROR);
|
||||
}
|
||||
}
|
||||
107
app/Middleware/Admin/PermissionMiddleware.php
Normal file
107
app/Middleware/Admin/PermissionMiddleware.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware\Admin;
|
||||
|
||||
use App\Annotation\Permission;
|
||||
use App\Constants\AdminCode;
|
||||
use App\Constants\Model\AdminUser\AdminUserStatusCode;
|
||||
use App\Exception\ErrException;
|
||||
use App\Lib\Jwt\RequestScopedTokenTrait;
|
||||
use App\Model\AdminUser;
|
||||
use App\Trait\AdminUserTrait;
|
||||
use App\Trait\ParserRouterTrait;
|
||||
use Hyperf\Collection\Arr;
|
||||
use Hyperf\Di\Annotation\AnnotationCollector;
|
||||
use Hyperf\HttpServer\Router\Dispatched;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
class PermissionMiddleware implements MiddlewareInterface
|
||||
{
|
||||
use RequestScopedTokenTrait;
|
||||
use AdminUserTrait;
|
||||
use ParserRouterTrait;
|
||||
|
||||
/**
|
||||
* @var AdminUser
|
||||
*/
|
||||
protected AdminUser $adminUserInfo;
|
||||
|
||||
/**
|
||||
* @param ContainerInterface $container
|
||||
*/
|
||||
public function __construct(protected ContainerInterface $container) {}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$adminId = $this->getToken()?->claims()?->get(RegisteredClaims::ID) ?? 0;
|
||||
if ($adminId <= 0) throw new ErrException('账户不存在');
|
||||
|
||||
$this->adminUserInfo = $this->getAdminUserInfo($adminId);
|
||||
if ($this->adminUserInfo->status == AdminUserStatusCode::DISABLE) throw new ErrException('账号已禁用',AdminCode::DISABLED);
|
||||
|
||||
// 超级管理员提前下场 不用判断权限
|
||||
if ($this->adminUserInfo->isSuperAdmin()) return $handler->handle($request);
|
||||
|
||||
$this->check($request->getAttribute(Dispatched::class));
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Dispatched $dispatched
|
||||
* @return bool
|
||||
*/
|
||||
private function check(Dispatched $dispatched): bool
|
||||
{
|
||||
$parseResult = $this->parse($dispatched->handler->callback);
|
||||
if (! $parseResult) return true;
|
||||
|
||||
[$controller, $method] = $parseResult;
|
||||
$annotations = AnnotationCollector::getClassMethodAnnotation($controller, $method);
|
||||
$classAnnotation = AnnotationCollector::getClassAnnotation($controller, Permission::class);
|
||||
/**
|
||||
* @var Permission[] $permissions
|
||||
*/
|
||||
$classAnnotation && $permissions[] = $classAnnotation;
|
||||
$methodPermission = Arr::get($annotations, Permission::class);
|
||||
$methodPermission && $permissions[] = $methodPermission;
|
||||
|
||||
foreach ($permissions as $permission) {
|
||||
$this->handlePermission($permission);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Permission $permission
|
||||
* @return void
|
||||
*/
|
||||
private function handlePermission(Permission $permission): void
|
||||
{
|
||||
$operation = $permission->getOperation();
|
||||
$codes = $permission->getCode();
|
||||
|
||||
foreach ($codes as $code) {
|
||||
$isMenu = $this->adminUserInfo->hasPermission($code);
|
||||
|
||||
if ($operation === Permission::OPERATION_AND && !$isMenu) throw new ErrException('暂无权限',AdminCode::FORBIDDEN);
|
||||
|
||||
if ($operation === Permission::OPERATION_OR && $isMenu) return;
|
||||
}
|
||||
|
||||
if ($operation === Permission::OPERATION_OR) throw new ErrException('暂无权限',AdminCode::FORBIDDEN);
|
||||
}
|
||||
}
|
||||
71
app/Middleware/Admin/RefreshAdminTokenMiddleware.php
Normal file
71
app/Middleware/Admin/RefreshAdminTokenMiddleware.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware\Admin;
|
||||
|
||||
use App\Constants\ResultCode;
|
||||
use App\Exception\ErrException;
|
||||
use App\Interface\JwtInterface;
|
||||
use App\Middleware\Token\AbstractTokenMiddleware;
|
||||
use Lcobucci\JWT\Token\RegisteredClaims;
|
||||
use Lcobucci\JWT\UnencryptedToken;
|
||||
use Lcobucci\JWT\Validation\RequiredConstraintsViolated;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
use Swow\Psr7\Message\ServerRequestPlusInterface;
|
||||
use function Hyperf\Support\env;
|
||||
use function Hyperf\Support\value;
|
||||
|
||||
class RefreshAdminTokenMiddleware extends AbstractTokenMiddleware
|
||||
{
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$this->checkToken->checkJwt($this->parserToken($request));
|
||||
$this->checkIssuer($this->parserToken($request));
|
||||
return $handler->handle(
|
||||
value(
|
||||
static function (ServerRequestPlusInterface $request, UnencryptedToken $token) {
|
||||
return $request->setAttribute('token', $token);
|
||||
},
|
||||
$request,
|
||||
$this->getJwt()->parserRefreshToken(
|
||||
$this->getToken($request)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JwtInterface
|
||||
*/
|
||||
public function getJwt(): JwtInterface
|
||||
{
|
||||
return $this->jwtFactory->get('admin');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @return UnencryptedToken
|
||||
*/
|
||||
protected function parserToken(ServerRequestInterface $request): UnencryptedToken
|
||||
{
|
||||
try {
|
||||
return $this->getJwt()->parserRefreshToken($this->getToken($request));
|
||||
} catch (RequiredConstraintsViolated $e) {
|
||||
throw new ErrException('token过期',ResultCode::JWT_EXPIRED,['err_msg' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param UnencryptedToken $token
|
||||
* @return void
|
||||
*/
|
||||
public function checkIssuer(UnencryptedToken $token): void
|
||||
{
|
||||
$audience = $token->claims()->get(RegisteredClaims::ISSUER);
|
||||
|
||||
if ($audience !== env('APP_NAME') .'_admin') throw new ErrException('token错误',ResultCode::JWT_ERROR);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user