Скрыть действия FW/1 без метода контроллера (только просмотр)

В настоящее время я использую концепцию «частиц» в своих представлениях FW/1: эти фрагменты макета, которые можно повторно использовать в разных представлениях. Они имеют префикс подчеркивания для упрощения обслуживания, но, в отличие от CFWheels, их все еще можно использовать как неявные представления, что не очень хорошо.

Например, есть структура каталогов:

/views/member/_user.cfm
/views/member/profile.cfm
/views/member/register.cfm

Таким образом, фактическая пользовательская форма находится в _user.cfm и может быть включена в две другие с помощью #view('member/_user')#.

Я хочу запретить доступ к таким страницам, как member._user на сайте.

Одним из решений является создание метода _user в контроллере member.cfc и перенаправление пользователя куда-либо. Но создание таких методов для каждого партиала — неэффективный подход.

Альтернативой этому может быть анализ rc.action в before и проверка наличия подчеркивания в префиксе, но я не уверен, что это чистое решение.

Можно ли отключить действие (бросить 404), если в контроллере нет соответствующего метода? Или, может быть, есть какие-то события/флаги фреймворка, которые позволили бы мне обработать ситуацию с «отсутствующим методом» в before?

Спасибо.


person Sergey Galashyn    schedule 31.05.2012    source источник
comment
Я думаю, вы можете установить _user() как частный, но я некоторое время не касался FW/1, чтобы узнать, работает ли это.   -  person Henry    schedule 31.05.2012
comment
@ Генри Я мог бы, но в том-то и дело - я не хочу создавать десятки пустых методов (у меня много партиалов).   -  person Sergey Galashyn    schedule 31.05.2012
comment
Использовать mod_rewrite для обнаружения URL-адресов, содержащих /_, и блокировать/перенаправлять в случае необходимости?   -  person Peter Boughton    schedule 31.05.2012
comment
@PeterBoughton Пожалуйста, опубликуйте это как ответ. Это похоже на предложение azawaza, но, по крайней мере, оно не будет включать вызов фреймворка/приложения, что хорошо для производительности.   -  person Sergey Galashyn    schedule 31.05.2012
comment
Не был уверен, что это считается ответом (скорее обходной путь), но ладно...   -  person Peter Boughton    schedule 31.05.2012


Ответы (4)


Вы можете создать метод в контроллере, который проверяет rc.action, чтобы увидеть, начинается ли часть item с _ и перенаправляет куда-то еще (или выдает ошибку, или что-то еще). Затем вызовите этот метод, используя функцию controller() в вашем методе setupRequest() в Application.cfc.

Например, у меня есть контроллер controllers/security.cfc с методом checkItem() следующим образом:

function checkItem( rc ) {
    //check if restricted item hss been requested and redirect to main.default
    if ( left(variables.fw.getItem(), 1) eq "_" ) {
        variables.fw.redirect('main');
    }
}

И вызовите его в setupRequest() в Application.cfc:

function setupRequest() {
    //controller( 'security.authorize' );
    controller( 'security.checkItem' );
}

Таким образом, он автоматически вызывается при каждом запросе — нет необходимости определять отдельный метод для каждого _item в контроллерах.

person azawaza    schedule 31.05.2012
comment
По сути, это то же самое, что я описал в абзаце, начинающемся с Alternative to this ..., но в любом случае спасибо. - person Sergey Galashyn; 31.05.2012
comment
использование метода before(), как вы упомянули, хотя и похоже, потребует от вас повторения одного и того же кода в каждом методе before() в каждом контроллере с ограниченными элементами; запустив его в setupRequest(), с другой стороны, у вас есть только ОДНО место, где находится код (security.cfc в моем примере кода). - person azawaza; 31.05.2012
comment
Ну, на самом деле вы можете иметь методы до/после в Application.cfc. - person Sergey Galashyn; 31.05.2012
comment
Я думаю, что этот подход лучше других, потому что он использует встроенные инструменты фреймворка, прост в реализации и не требует внешней настройки. Давайте рассмотрим этот правильный ответ. - person Sergey Galashyn; 01.06.2012

Самый простой способ сделать это — поместить их в папку, которая не находится в корневом каталоге. Поэтому они не доступны в Интернете. Затем используйте сопоставление ColdFusion, чтобы сделать их доступными для ColdFusion.

Есть смысл?

person baynezy    schedule 01.06.2012
comment
Может быть, это было бы в некоторых случаях. Но это добавило бы еще один уровень сложности со структурой репозитория, рабочим процессом и IDE (фактически вторым проектом) лично для меня. - person Sergey Galashyn; 01.06.2012
comment
@Sergii это общепринятый способ добиться того, о чем вы просите. Вам не нужно создавать новый проект. Вы можете просто иметь структуру папок, которая поддерживает это. т. е. /www/ (это ваш веб-сайт) /views/ (это то место, где находятся ваши взгляды), тогда вы продвигаете его как сопоставление. Маршрут mod_rewrite будет работать, но это немного кувалдный подход к тому, что может быть решено самим CF. - person baynezy; 01.06.2012
comment
Извините, но это не так. Мы говорим здесь о FW/1, верно?. Структура проекта определяется структурой — она основана на соглашениях. Можно переопределить его (конечно), но это не выглядит разумным выбором для долгосрочного обслуживания. Например, если некоторые другие приложения имеют стандартную структуру, это может привести к путанице. - person Sergey Galashyn; 01.06.2012
comment
Я знаю это. Однако его волнует только то, где, по мнению ColdFusion, он находится, поэтому создание сопоставления дает ему ответ. Это, очевидно, ваш выбор, но я думаю, что вы просто усложняете себе жизнь. - person baynezy; 01.06.2012
comment
Вы знаете, я думаю, что ваш ответ был неправильным с самого начала. Допустим, я создал сопоставление для представлений, которые на самом деле лежат за пределами веб-корня. Но проблема в том, что приложение думает, что это обычные представления, и все неявные действия будут работать как обычно, включая партиалы. Я need сделал их доступными для приложения, чтобы включить их в обычные представления. - person Sergey Galashyn; 01.06.2012
comment
Но это то, что делает отображение. По сути, ColdFusion увидит их так, как будто они находятся там, где вы хотите, но ваш веб-сервер не увидит. - person baynezy; 02.06.2012
comment
Да, но проблема не в прямом доступе к шаблонам (переписывание все равно не позволит), а в явных действиях, возможных только с представлениями. - person Sergey Galashyn; 02.06.2012

Вы можете использовать mod_rewrite для обнаружения URL-адресов, содержащих /_, и блокировки/перенаправления в зависимости от ситуации. .

Например:

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/\w+/_
RewriteRule ^.* /error/404 [L]


Первый RewriteCond гарантирует, что файл не существует, поэтому, если у вас есть настоящий файл, /css/_default.css любые запросы к нему не удовлетворят этому условию и не будут перенаправлены.

Второй RewriteCond принимает любые буквенно-цифровые символы для первого сегмента, а затем продолжает работу, если в начале второго сегмента есть _. (Не обязательно сопоставлять весь URI, достаточно только начала.)

Наконец, RewriteRule применяется, только если оба условия были истинными, но соответствует всем URL-адресам и выполняет перенаправление на стороне сервера на /error/404 — вы можете обновить эту часть по мере необходимости. (Флаг [L] указывает mod_rewrite не предпринимать дальнейших попыток перезаписи.)

person Peter Boughton    schedule 31.05.2012

Хорошо, так как ответа, которого я ожидал, нет (и это нормально), вот еще один подход, который я уже использую для шаблонов электронной почты.

В /views/emails/ все представления являются шаблонами электронной почты, которые не имеют действий, а вызываются только так:

local.body = variables.fw.view("emails/registration_confirmation", local.attrs);
local.template = variables.fw.view("emails/default", {body = local.body});

Где registration_confirmation.cfm — это шаблон для конкретного тела письма, а default.cfm (можно назвать по-другому) — сам шаблон письма.

Чтобы предотвратить проблему, которую я описал в вопросе, контроллер emails.cfc выглядит так:

component extends="components.helpers.controller" {

    public void function before(required struct rc) {
        variables.fw.redirect("user.forbidden");
    }

}

Думаю, можно было бы создать еще один такой контроллер partials.cfc и хранить все представления в /views/partials/.

Но это мой первый реальный проект FW/1, и я слишком поздно пришел к идее рефакторинга такого количества представлений (1), плюс я думаю, что партиалы в одном каталоге хуже с точки зрения обслуживания, чем их где это имеет смысл для них (2).

Вот две причины, по которым я задал этот вопрос.

person Sergey Galashyn    schedule 01.06.2012