cakePHP:根据用户角色在传递给视图之前过滤行

Posted

技术标签:

【中文标题】cakePHP:根据用户角色在传递给视图之前过滤行【英文标题】:cakePHP: filter rows before passing to view based on user role 【发布时间】:2014-09-10 11:39:18 【问题描述】:

我开发了一个 cakephp 应用程序来管理一些书籍,它使用 'Auth' 组件作为其身份验证机制。我有 2 个用户角色:管理员和用户。在这个应用程序中,我对 Book 及其索引视图有以下规则:

    每个管理员都可以查看、编辑所有图书并... 每个普通用户只能查看他/她的书籍,只能编辑他/她的书籍(不是所有书籍)

换句话说,我想知道在将模型信息传递给视图之前是否可以根据用户角色过滤数据?

我猜想将所有数据传递给视图,然后根据视图内的用户角色过滤它们,可能会导致数据库开销,但我不确定我是否正确。 目前我的 index.ctp 是这样的,它只显示与登录用户相关的书籍(不关心他的角色):

<div class="books index">
<h2><?php echo __('Books'); ?></h2>
<?php if ($loggedIn)  ?>
    <table cellpadding="0" cellspacing="0">
        <thead>
            <tr>
                <th><?php echo $this->Paginator->sort('id'); ?></th>
                <th><?php echo $this->Paginator->sort('book_user_id'); ?></th>
                <th><?php echo $this->Paginator->sort('name'); ?></th>
                <th><?php echo $this->Paginator->sort('revision'); ?></th>
                <th><?php echo $this->Paginator->sort('price'); ?></th>
                <th><?php echo $this->Paginator->sort('publication_year'); ?></th>
                <th><?php echo $this->Paginator->sort('url_cover_page'); ?></th>
                <th><?php echo $this->Paginator->sort('url_last_page'); ?></th>
                <th><?php echo $this->Paginator->sort('author'); ?></th>
                <th><?php echo $this->Paginator->sort('publisher'); ?></th>
                <th><?php echo $this->Paginator->sort('translator'); ?></th>
                <th><?php echo $this->Paginator->sort('tags'); ?></th>
                <th><?php echo $this->Paginator->sort('created'); ?></th>
                <th><?php echo $this->Paginator->sort('modified'); ?></th>
                <th class="actions"><?php echo __('Actions'); ?></th>
            </tr>
        </thead>
        <tbody>
            <?php foreach ($books as $book): ?>
                <?php if ($book['BookUser']['id'] == $loggedIn)  ?>
                    <tr>
                        <td><?php echo h($book['Book']['id']); ?>&nbsp;</td>
                        <td>
                            <?php echo $this->html->link($book['BookUser']['username'], array('controller' => 'users', 'action' => 'view', $book['BookUser']['id'])); ?>
                        </td>
                        <td><?php echo h($book['Book']['name']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['revision']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['price']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['publication_year']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['url_cover_page']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['url_last_page']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['author']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['publisher']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['translator']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['tags']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['created']); ?>&nbsp;</td>
                        <td><?php echo h($book['Book']['modified']); ?>&nbsp;</td>
                        <td class="actions">
                            <?php echo $this->Html->link(__('View'), array('action' => 'view', $book['Book']['id'])); ?>
                            <?php echo $this->Html->link(__('Edit'), array('action' => 'edit', $book['Book']['id'])); ?>
                            <?php echo $this->Form->postLink(__('Delete'), array('action' => 'delete', $book['Book']['id']), array(), __('Are you sure you want to delete # %s?', $book['Book']['id'])); ?>
                        </td>
                    </tr>
                <?php  ?>
            <?php endforeach; ?>
        </tbody>
    </table>
<?php  else  ?>
    <p>To view your books, please login or Sign Up.</p>
<?php  ?>
<p>
    <?php
    echo $this->Paginator->counter(array(
        'format' => __('Page :page of :pages, showing :current records out of :count total, starting on record :start, ending on :end')
    ));
    ?>  </p>
<div class="paging">
    <?php
    echo $this->Paginator->prev('< ' . __('previous'), array(), null, array('class' => 'prev disabled'));
    echo $this->Paginator->numbers(array('separator' => ''));
    echo $this->Paginator->next(__('next') . ' >', array(), null, array('class' => 'next disabled'));
    ?>
</div>

Html->link(__('New Book'), array('action' => 'add')); ?> Html->link(__('List Users'), array('controller' => 'users', 'action' => 'index')); ?> Html->link(__('New Book User'), array('controller' => 'users', 'action' => 'add')); ?> Html->link(__('List Pgs'), array('controller' => 'pgs', 'action' => 'index')); ?> Html->link(__('New Book Pgs'), array('controller' => 'pgs', 'action' => 'add')); ?>

【问题讨论】:

【参考方案1】:

您不应该检索数据,更不用说将所有数据发送到视图。您应该根据当前登录用户的角色在模型查询中进行过滤。然后传下去。

如果由于某种原因难以在实际查询中过滤(不确定为什么会这样),我建议仍然使用 Cake 的 Hash 或 php 数组函数过滤 Model 方法中的数据....等等,具体取决于在传递回控制器之前您的需求。

在您看来,为不同的显示块编写 if 语句是可以接受的,但这取决于用户的角色。

【讨论】:

所以您建议根据用户角色过滤视图中的信息? "你应该在你的模型中过滤..." 你能举个例子吗? 如果您提出具体问题,我很乐意回答,但我不会为您编写代码。 我不知道如何在模型中过滤数据,不幸的是我不知道如何编写代码。我的意思是任何有关此的文档或参考资料,因为我确实搜索过但一无所获。

以上是关于cakePHP:根据用户角色在传递给视图之前过滤行的主要内容,如果未能解决你的问题,请参考以下文章

将数据从 cakephp 视图传递给控制器

cakephp:从下拉列表中为报告添加过滤器

如何将身份用户及其身份角色传递给视图?

如何根据 JSON 数据和过滤参数过滤列表视图?

Cakephp - 多个视图一个控制器-功能

CakePHP Auth 组件中的角色