Yii2 получает доступ только по красивым URL-адресам

#yii2 #yii2-basic-app

#yii2 #yii2-basic-app

Вопрос:

Я использую диспетчер URL следующим образом:

 'urlManager' => [
            'enablePrettyUrl' => true,
            'showScriptName' => false,
            'rules' => [                
                'verses/view/<id:d >' => 'verses/view',                
            ],
        ],
 

Он отлично работает, чтобы сделать доступ с помощью mysite.com/verses/view/158 . Проблема в том, что по-прежнему можно получить доступ к тому же контенту, используя не красивый URL, т.е. Используя простой параметр get, такой как mysite.com/verses/view?id=158 . Мне нужен любой способ ограничить доступ с помощью красивого URL.

Я попробовал следующие пары правил отдельно, но ничего не получил:

  1. 'verses/view<?id=>' => 'Error404',
  2. 'verses/view?id=<d >' => 'Error404',

Ответ №1:

В чем смысл такого ограничения?

В любом случае, один из способов сделать это примерно так:

 public function actionView($id)
{
    if (strpos(Yii::$app->request->getUrl(), '?') !== false) {
        throw new yiiwebBadRequestHttpException;
    }
    // ... the rest of action
}
 

Никаких изменений в urlManager не требуется.

Комментарии:

1. Также это может быть обобщено на все действия контроллера с помощью этой проверки beforeAction

Ответ №2:

Попробуйте использовать UrlManager параметр enableStrictParsing = true .

Что происходит. urlManager проверяет все правила, и все они не соответствуют запросу. Таким образом, по умолчанию он проверяет все правила по умолчанию. Среди правил по умолчанию он находит правило с ?id= и предварительно формирует маршрутизацию к нему.

Итак, чтобы избежать этого маршрута, вам нужно перечислить все возможные маршруты в UrlManger правилах и make enableStrictParsing = true . Маршруты, не указанные в параметре config rules , будут проигнорированы.

Комментарии:

1. Это хорошее решение. Тем не менее, будет обязательно составить очень большой список правил для каждого публичного действия, к которому приложение должно быть доступно. Это усложнит ситуацию.

2. Вам просто нужно использовать более общие правила, такие как <module:w >/<controller:w >/<action:w >