Flash 消息在 CakePHP3 视图中显示两次

Flash message shows twice in a view CakePHP3

我已经多次遇到这个问题,并试图通过删除调用 Flash 方法来避免它。最近,我想向尝试注销的未登录用户显示错误提示。但是,当我测试此操作时(通过访问 localhost:8765/users/logout 而无需登录),一切正常,除了我收到 2 条错误消息 "You are not authorized to access this location"。我该如何解决这个问题?

这是我的代码

在 AppController 中:

public function initialize()
{
    parent::initialize();

    $this->loadComponent('RequestHandler');
    $this->loadComponent('Flash');
    $this->loadComponent('Auth', [
        'authorize' => ['Controller'],  //For User authorize checking, this tells app to let each controller decides own rules for authorize
       'loginRedirect' => ['controller' => 'Articles', 'action' => 'index'],
       'logoutRedirect' => ['controller' => 'Users', 'action' => 'index']
    ]);
}

public function beforeFilter(Event $event)
{
    //this applied to every controller
    $this->Auth->allow(['index', 'view', 'display']);
}

  ...

public function isAuthorized($user)
{
    //Admin can access every action
    if(isset($user['role']) && $user['role'] === 'admin'){
        return true;
    }

    //Default deny
    return false;
}

在用户控制器中:

public function isAuthorized($user)
{
    //All registered users can add articles
    if($this->request->action === 'add'){
        return true;
    }

    //The self user can edit and delete the account
    if(in_array($this->request->action, ['edit', 'delete'])){            
        //get id of targeted user
        $targetUserId = (int)$this->request->params['pass'][0];
        //check if current user is the targeted user
        if($this->Users->selfUser($targetUserId, $user['id'])){
            return true;
        }else{
            $this->Flash->error(__('You are not authorized for this action'));
        }
    }
    return parent::isAuthorized($user);
}

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);
    $this->Auth->allow(['add']);
}

...

public function logout()
{
    return $this->redirect($this->Auth->logout());
}

在用户表中

public function selfUser($targetedUserId, $userId)
{

    return $targetedUserId == $userId;
}

在default.ctp

$cakeDescription = 'CakePHP: the rapid development php framework';
?>
<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <?= $cakeDescription ?>:
        <?= $this->fetch('title') ?>
    </title>
    <?= $this->Html->meta('icon') ?>

    <?= $this->Html->css('base.css') ?>
    <?= $this->Html->css('cake.css') ?>

    <?= $this->fetch('meta') ?>
    <?= $this->fetch('css') ?>
    <?= $this->fetch('script') ?>
</head>
<body>
    <nav class="top-bar expanded" data-topbar role="navigation">
        <ul class="title-area large-3 medium-4 columns">
            <li class="name">
                <h1><a href=""><?= $this->fetch('title') ?></a></h1>
            </li>
        </ul>
        <div class="top-bar-section">
            <ul class="right">
                <li><a target="_blank" href="http://book.cakephp.org/3.0/">Documentation</a></li>
                <li><a target="_blank" href="http://api.cakephp.org/3.0/">API</a></li>
            </ul>
        </div>
    </nav>
    <?= $this->Flash->render() ?>
    <div class="container clearfix">
        <?= $this->fetch('content') ?>
    </div>
    <footer>
    </footer>
</body>
</html>

在login.ctp

<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __('Please enter your username and password') ?></legend>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('password') ?>
    </fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>

您能否也 post 甚至只是从您的 CTP 文件中摘录?有可能在页面布局中 Flash 被渲染了两次。

您必须在注销操作中添加此行:

$this->autoRender = false;

因此,在您的情况下,您的 UsersController 应该是:

public function isAuthorized($user)
{
    //All registered users can add articles
    if($this->request->action === 'add'){
        return true;
    }

    //The self user can edit and delete the account
    if(in_array($this->request->action, ['edit', 'delete'])){            
        //get id of targeted user
        $targetUserId = (int)$this->request->params['pass'][0];
        //check if current user is the targeted user
        if($this->Users->selfUser($targetUserId, $user['id'])){
            return true;
        }else{
            $this->Flash->error(__('You are not authorized for this action'));
        }
    }
    return parent::isAuthorized($user);
}

public function beforeFilter(Event $event)
{
    parent::beforeFilter($event);
    $this->Auth->allow(['add']);
}

...

public function logout()
{
    $this->autoRender = false;
    return $this->redirect($this->Auth->logout());
}