问题描述
大家。如果之前有人问过这个问题,我深表歉意,但我很难找到关于这个主题的任何。
我在我的应用程序中加载了 Authorization 插件,它工作正常,除了当用户没有被授权做某事时返回的消息。例如,只有站点管理员可以对用户帐户执行任何操作:
psql -U Postgres
在 UsersController 中调用 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);
}
有效,任何没有站点管理员组权限的人都会被禁止,但是我如何自定义未经授权的用户看到的错误消息并将其重定向到其他地方?似乎没有明显的方法可以做到这一点。
解决方法
重定向
如评论中所述,如果重定向没有发生,那么您可能没有为该异常导入(正确的)FQN,它应该是:
\Authorization\Exception\ForbiddenException
在授权中间件的 unauthorizedHandler
配置中使用它应该可以使用文档中显示的示例正常工作,例如:
$middlewareQueue->add(
new \Authorization\Middleware\AuthorizationMiddleware($this,[
'unauthorizedHandler' => [
'className' => 'Authorization.Redirect','url' => '/users/login','queryParam' => 'redirectUrl','exceptions' => [
\Authorization\Exception\ForbiddenException::class,],])
);
这将涵盖重定向部分。如果您还想向用户显示一条消息,那么您几乎有两种选择,要么重定向到包含或多或少硬编码消息的页面,要么使用您自己的重定向处理程序并设置一个 flash 消息。
设置快闪信息
后者的一个简单示例可能如下所示:
<?php
// in src/Middleware/UnauthorizedHandler/FlashRedirectHandler.php
namespace App\Middleware\UnauthorizedHandler;
use Authorization\Exception\Exception;
use Authorization\Middleware\UnauthorizedHandler\RedirectHandler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
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 \Cake\Http\FlashMessage $flash */
$flash = $request->getAttribute('flash');
$flash->error($message);
return $response;
}
}
'unauthorizedHandler' => [
'className' => \App\Middleware\UnauthorizedHandler::class,// ...
],
在 CakePHP 4.2 中引入了 flash 消息类,在早期版本中,您必须手动写入会话,这不是太好:
/** @var \Cake\Http\Session $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
您应该找到一种更好的方法来获取身份组,恕我直言,在您的策略中具有会话等依赖项注定会给您带来麻烦。
理想情况下,身份应该包含它所属的组,这样您就可以简单地执行以下操作:
return in_array('site_admin',$user['groups'],true);