В AngularJS реализована поддержка JSON Vulnerability Protection, направленная на то, чтобы противодействовать ситуациям, когда злоумышленник может, при определённых условиях, превратить JSON в JSONP и выполнить какой-то код. В качестве меры противодействия на серверной стороне предлагается добавлять к JSON-данным такой префикс:
Под катом — моя короткая история генерации JSON-данных с префиксом. Но, я думаю, эта история так же хорошо иллюстрирует и более общий вопрос — как можно добавлять свои собственные форматы ответов сервера. В Yii Framework это делается довольно-таки просто — для этого достаточно описать в конфигурации, какой класс будет отвечать за генерацию ответа определённого формата.
Я начал с того, что добавил в конфигурацию (/путь_к_проекту/config/web.php — раздел components → response → formatters) новый тип ответа — «jsonvp», назначив для него класс, который я собираюсь создать.
В классе
Осталось только проверить функционал:
При вызове
С помощью такого нехитрого способа можно создавать собственные форматы ответов. Например, как описано выше, — JSON с префиксом, позволяющим защититься от уязвимости.К сожалению, в книге рецептов по фреймворку на текущий момент нет описания того, как создавать собственные форматы ответов, хотя раздел и помечен меткой «TBD». Upd: Уже есть.
Надеюсь, кому-нибудь эта статья будет полезной. Удачи!
)]}',
Под катом — моя короткая история генерации 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'];
}
}
При вызове
localhost/index.php?r=site/json
в браузере выводится такой результат:)]}',
["123","456"]
Заключение
С помощью такого нехитрого способа можно создавать собственные форматы ответов. Например, как описано выше, — JSON с префиксом, позволяющим защититься от уязвимости.
Надеюсь, кому-нибудь эта статья будет полезной. Удачи!