У меня есть контроллер под названием «Учетные записи», с надписью «signin» и «signout».
Соответствующие функции выглядят так:
function signin() { if (!empty($this->data)) { //handle login ... //save login to session $this->Session->write('Account', $data["Account"]); //redirect to previous page ??? } } function signout() { //delete login $this->Session->delete('Account'); //redirect to previous page ??? }
Если пользователь переходит к accounts/signin
он сначала проверяет, отправлена if(!empty($this->data))
форма, if(!empty($this->data))
Empty if(!empty($this->data))
если да, она регистрирует их, если не отображает форму. Если они успешно вошли в систему, я хочу перенаправить их на страницу, на которой они были до страницы входа.
Каков наилучший способ сделать это?
Редактировать:
Я не думаю, что я могу использовать обычный HTTP-реферер, потому что технически реферер всегда будет signin на странице, потому что они идут в /signin
, а затем представляют форму входа. Таким образом, в момент подачи формы реферер всегда /signin
. Я хочу перенаправить туда, где они были до этого. Имеет ли это смысл?
http://book.cakephp.org/view/430/referer
Используйте скрытое поле <input>
которое содержит исходный реферер и отправляется с данными входа.
лучший способ – использовать компонент Cake Cake и позволить ему делать то, что он делает … http://book.cakephp.org/2.0/ru/core-libraries/components/authentication.html#AuthComponent::$loginRedirect
Вот как я это делаю с рефером
У меня есть 2 формы входа, одна из них – верхняя часть всех страниц для входа в систему, другая – в действии входа. Если пользователь приходит с использованием формы вверху, форма отправки затем переходит на страницу входа, и вы можете использовать $this->referer()
для перенаправления пользователя.
Но проблема в том, что, если пользователь вводит неверный пароль или вводит недопустимые учетные данные, он затем попадает на страницу входа в систему. Если он затем вводит правильное имя пользователя + пароль, а перенаправление происходит с помощью $this->referer()
, которое в этом случае само. Затем пользователь мог либо 1. снова перенаправить на страницу входа в систему, либо 2. еще хуже может застрять в бесконечном цикле. B / c login будет перенаправлять на себя.
Итак, я добавляю логику, чтобы проверить, что референт не является страницей входа в систему. Кроме того, я добавляю еще одну логику для хранения $this->referer()
при первом $this->referer()
пользователя на страницу входа, мы знаем, где именно страница перед страницей входа.
Чтобы сохранить страницу перед страницей входа в систему, поместите этот код в конец действия (начнется просмотр в режиме просмотра)
//get the current url of the login page (or current controller+action) $currentLoginUrl = strtolower( "/" .$this->name ."/" .$this->action ); if( $this->referer() != $currentLoginUrl ) { //store this value to use once user is succussfully logged in $this->Session->write('beforeLogin_referer', $this->referer($this->Auth->redirect(), true)) ) ; //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead }
Теперь добавьте код для переадресации в той части кода, где выполняется проверка подлинности (или в if( $this->Auth->user() ){ }
):
//get the login page url again (by gettting its controller, or plural of Model, and this current page action and make the url) $currentLoginUrl = strtolower( "/" .$this->name ."/" .$this->action ); //if the referer page is not from login page, if( $this->referer() != $currentLoginUrl ) { //use $this->referer() right away $this->redirect($this->referer($this->Auth->redirect(), true)); //if referer can't be read, or if its not from local server, use $this->Auth->rediret() instead } else { //if the user lands on login page first, rely on our session $this->redirect( $this->Session->read('beforeLogin_referer') ); }
Надеюсь, что это работает для вас.
Я не знаю о лучшем способе, но я сохраняю попытку назначения в переменной сеанса, прежде чем перенаправлять их на страницу входа.
После того, как они вошли в систему, я перенаправляю их на сохраненное место назначения.
CakePHP 2.x здесь
public function beforeFilter() { // redirect url if($this->request->here!= '/users/login') { $user_id = AuthComponent::user('id'); if(empty($user_id)) { $this->Session->write('redirect_url_after_login', Router::url($this->request->here, true)); } }
Это сохранит URL-адрес, который пользователь хочет выполнить перед запросом, только если URL-адрес не является / users / login (замените его URL-адресом логина) И если ни один пользователь не зарегистрирован.
$redirect_url_after_login = $this->Session->read('redirect_url_after_login'); if(!empty($redirect_url_after_login)) echo $this->Form->input('redirect_url_after_login', ['value'=>$redirect_url_after_login, 'type'=>'hidden']);
public function login() { if ($this->request->is('post')) { if ($this->Auth->login()) { $redirect_url_after_login = $this->request->data['User']['redirect_url_after_login']; if(!empty($redirect_url_after_login) &&filter_var($redirect_url_after_login, FILTER_VALIDATE_URL) &&parse_url($redirect_url_after_login, PHP_URL_HOST)==$_SERVER['HTTP_HOST']) return $this->redirect($redirect_url_after_login); $this->Session->delete('redirect_url_after_login'); return $this->redirect($this->Auth->redirect());
}
Я добавил пару проверок безопасности, например, "является ли URL перенаправления действительным URL?" и «перенаправляется ли он на мой домен или внешний домен?».
Примечание. Я знаю, что проверка $_SERVER['HTTP_HOST']
не является пуленепробиваемой, но здесь мы говорим о предотвращении открытой переадресации уязвимости, поэтому этого достаточно.
Используйте AppController и UserController для его настройки.
В приложении AppController beforeFilter
$referer = Router::url($this->url, true); $this->Auth->loginAction = array('controller'=>'users','action'=>'login','?'=>['referer'=>$referer]);
В действии входа в UserController
if($this->Auth->login()) { $this->Session->setFlash(__('Logged in successfully !')); $redirect = $this->request->query('referer'); if(!empty($redirect)) { return $this->redirect($this->Auth->redirectUrl($redirect)); }else{ return $this->redirect($this->Auth->redirectUrl()); } }