每个人。如果以前有人问过这个问题,我很抱歉,但我很难找到关于这个主题的任何东西。
我在我的应用程序中加载了授权插件,它运行良好,除了用户在未被授权做某事时收到的消息。例如,只有站点管理员可以对用户帐户执行任何操作:
public function canAdd(IdentityInterface $user, User $resource)
{
// Site admins can add users
$session = Router::getRequest()->getSession();
$groups = $session->read('groups');
return in_array('site_admin', $groups);
}
在UsersController中调用$this->Authorization->authorize($user)
是有效的,任何没有站点管理员组权限的人都会被禁止,但我如何自定义未经授权的用户看到的错误消息并将其重定向到其他地方?似乎没有明显的方法可以做到这一点。
重定向
正如评论中所提到的,如果重定向没有发生,那么您可能没有为该异常导入(正确的)FQN,它应该是:
AuthorizationExceptionForbiddenException
在授权中间件的unauthorizedHandler
配置中使用它应该可以很好地使用文档中显示的示例,例如:
$middlewareQueue->add(
new AuthorizationMiddlewareAuthorizationMiddleware($this, [
'unauthorizedHandler' => [
'className' => 'Authorization.Redirect',
'url' => '/users/login',
'queryParam' => 'redirectUrl',
'exceptions' => [
AuthorizationExceptionForbiddenException::class,
],
],
])
);
这将涵盖重定向部分。如果你还想向用户显示一条消息,那么你几乎有两个选项,要么重定向到一个或多或少有硬编码消息的页面,要么使用你自己的重定向处理程序并设置一条flash消息。
设置闪烁信息
后者的一个简单示例如下:
<?php
// in src/Middleware/UnauthorizedHandler/FlashRedirectHandler.php
namespace AppMiddlewareUnauthorizedHandler;
use AuthorizationExceptionException;
use AuthorizationMiddlewareUnauthorizedHandlerRedirectHandler;
use PsrHttpMessageResponseInterface;
use PsrHttpMessageServerRequestInterface;
class FlashRedirectHandler extends RedirectHandler
{
public function handle(
Exception $exception,
ServerRequestInterface $request,
array $options = []
): ResponseInterface
{
$response = parent::handle($exception, $request, $options);
$message = sprintf(
'You are not authorized to access the requested resource `%s`.',
$request->getRequestTarget()
);
/** @var CakeHttpFlashMessage $flash */
$flash = $request->getAttribute('flash');
$flash->error($message);
return $response;
}
}
'unauthorizedHandler' => [
'className' => AppMiddlewareUnauthorizedHandler::class,
// ...
],
flash消息类是在CakePHP 4.2中引入的,在早期版本中,您必须手动写入会话,这并不太好:
/** @var CakeHttpSession $session */
$session = $request->getAttribute('session');
$messages = (array)$session->read('Flash.flash', []);
$messages[] = [
'message' => $message,
'key' => 'flash',
'element' => 'flash/error',
'params' => [],
];
$session->write('Flash.flash', $messages);
ps
您应该找到一种更好的方法来获得身份组,IMHO在您的策略中具有会话等依赖关系注定会给您带来麻烦。
理想情况下,身份应该包含它所属的组,这样你就可以简单地执行:
return in_array('site_admin', $user['groups'], true);
请参阅CakePHP身份验证插件标识关联