编程语言
首页 > 编程语言> > php – 锂内容协商显示所有数据 – 如何过滤掉它?

php – 锂内容协商显示所有数据 – 如何过滤掉它?

作者:互联网

我有app / controllers / UsersController.php做一个简单的Users :: find(‘all’);在索引动作中.

路径/ users / index呈现用户数据的纯HTML输出.
路径/users/index.json呈现了与HTML输出相当的JSON,除了它还暴露了密码(经过哈希处理,但仍然……)这一事实.

我看到两种方法可以避免这种情况:

>在我的finder中明确指定字段.
> Filter Media :: render()并取消设置任何敏感数据.

从长远来看,我觉得#2可能更容易维护.
任何意见?还有第三种更好的选择吗?

这就是我实现#2的方式:

<?php

namespace app\controllers;

use \lithium\net\http\Media;

class UsersController extends \lithium\action\Controller {
    protected function _init() {
        Media::applyFilter('render', function($self, $params, $chain) {
            if ($params['options']['type'] === 'json') {
                foreach ($params['data']['users'] as $user) {
                    $user->set([
                        'password' => null,
                        'salt' => null
                    ]);
                }
            }
            return $chain->next($self, $params, $chain);
        });
        parent::_init();
    }
}
?>

任何意见,将不胜感激.

解决方法:

这个问题可以有很多答案和方法,取决于你的应用程序,可维护性,架构的优雅等等……
如果您只想删除用户密码等敏感字段,您的解决方案就可以完成这项工作.

但!

过滤Media :: render()似乎根本不是一个好主意.你在这里混淆了问题,你最终会得到一个膨胀的过滤器,你可以在其中调整一个对象来删除你不希望在json响应中公开的内容.

对于应用中的每个控制器,如果每次必须对其进行点对,则使用字段可能不够好.更糟糕的是,如果您的实体有30个字段,并且根据当前用户,显示不同的信息(OMG)!
你最终会得到一个膨胀的控制器,你再次混淆了关注点和责任:find()负责读取你的数据,而field只是为了改变数据的表示(视图).

所以?我们能做什么?

复制控制器逻辑
您可以将控制器中的过滤逻辑分隔为if($this-> request-> is(‘json’)){…}
这意味着如果请求是html或json(公共API),则相同的控制器操作会有不同的响应.
这也不好:)
稍微好一点的方法是通过重复控制器来分解一些东西=>第一组负责你的json api,第二组负责响应html的“经典”控制器.
您可以通过添加控制器/ api命名空间轻松地使用Lithium执行此操作,并在json请求/响应的情况下使用此路径来执行此操作.

li3_jbuilder
在某些情况下,我对复制控制器并不满意.一个更好的方法是使用MVC的V部分,但这次渲染json响应,并将它们作为第一类对象处理:json视图!
这可以通过调整Media类配置和使用回退机制(如果找不到* .json.php,json_encode没有过滤字段的对象)来轻松完成.
我为Lithium构建了li3_jbuilder,以便轻松构建json响应,嵌套对象,使用帮助程序,并将“表示”方面移动到视图层.
Jbuilder的灵感来自Rails的jbuilder.仅供参考,ruby社区也获得了RABL.

演示者模式
虽然这种方法看起来很简单,但还有一个有趣的方法,更多面向对象:使用Presenter模式(或Decorator).
用户模型与UserPresenter类(普通的旧类)相关联,负责提供要“呈现”的对象,尤其是在json响应中(或应用程序中的任何位置).
演示者还可以帮助您清理复杂的视图逻辑,可测试且非常灵活.
演示者需要知道模型和它将要处理的视图,因此您将这些传递给初始化方法并将它们分配给实例变量.
只是谷歌的“Presenter模式”,或“Rails演示者”(我使用的唯一框架,利用这种模式),以了解更多关于这个主题

标签:php,json,lithium,content-negotiation
来源: https://codeday.me/bug/20190831/1776732.html