В AngularJS реализована поддержка JSON Vulnerability Protection, направленная на то, чтобы противодействовать ситуациям, когда злоумышленник может, при определённых условиях, превратить JSON в JSONP и выполнить какой-то код. В качестве меры противодействия на серверной стороне предлагается добавлять к JSON-данным такой префикс: )]}',
Под катом — моя короткая история генерации JSON-данных с префиксом. Но, я думаю, эта история так же хорошо иллюстрирует и более общий вопрос — как можно добавлять свои собственные форматы ответов сервера. В Yii Framework это делается довольно-таки просто — для этого достаточно описать в конфигурации, какой класс будет отвечать за генерацию ответа определённого формата.
Я начал с того, что добавил в конфигурацию (/путь_к_проекту/config/web.php — раздел components → response → formatters) новый тип ответа — «jsonvp», назначив для него класс, который я собираюсь создать.
<?php // . . . $config = [ // . . . 'components' => [ // . . . 'response' => [ 'formatters' => [ 'jsonvp' => 'app\components\JsonVpResponseFormatter', ], ], ], // . . . ];
В классе yii\web\Response
есть свойство $formatters
, которое дополнится тем, что есть в конфигурации. И теперь, если в каком-то экшене задать Yii::$app->response->format = 'jsonvp';
, то он будет использовать для форматирования ответа класс app\components\JsonVpResponseFormatter
. Во фреймворке есть интерфейс yii\web\ResponseFormatterInterface
, который регулирует правила написания таких классов, так что можно применить к моему новому классу этот интерфейс.
<?php namespace app\components; use yii\helpers\Json; use yii\web\Response; use yii\web\ResponseFormatterInterface; class JsonVpResponseFormatter implements ResponseFormatterInterface { /** * Format as Vulnerability Protected JSON. * @param Response $response */ public function format($response) { $response->getHeaders()->set('Content-Type', 'application/json; charset=UTF-8'); if ($response->data !== null) { $response->content = ")]}',\n" . Json::encode($response->data); } } }
Осталось только проверить функционал:
<?php namespace app\controllers; use Yii; use yii\web\Controller; /** * site/* actions. * @package app\controllers */ class SiteController extends Controller { /** * Test JSON output * @return array */ public function actionJson() { Yii::$app->response->format = 'jsonvp'; return ['123', '456']; } }
При вызове http://localhost/index.php?r=site/json
в браузере выводится такой результат:
)]}', ["123","456"]
Заключение
С помощью такого нехитрого способа можно создавать собственные форматы ответов. Например, как описано выше, — JSON с префиксом, позволяющим защититься от уязвимости. К сожалению, в книге рецептов по фреймворку на текущий момент нет описания того, как создавать собственные форматы ответов, хотя раздел и помечен меткой «TBD». Надеюсь, кому-то эта статья поможет. Удачи!
ссылка на оригинал статьи http://habrahabr.ru/post/256213/
Добавить комментарий