Вопрос:
Это похоже на довольно простой поток, и Laravel имеет так много хороших решений для основных вещей, я чувствую, что что-то не хватает.
Пользователь нажимает ссылку, требующую аутентификации. Фильтр авторизации Laravel запускается и направляет их на страницу входа. Пользователь входит в систему, затем переходит на исходную страницу, к которой они пытались добраться, прежде чем выйдет фильтр “auth”.
Есть ли хороший способ узнать, на какой странице они пытались добраться до изначально? Поскольку Laravel – это тот, кто перехватывает запрос, я не знал, отслеживает ли он где-нибудь удобную маршрутизацию после входа пользователя в систему.
Если нет, мне было бы интересно узнать, как некоторые из вас выполнили это вручную.
Лучший ответ:Содержание
- Для Laravel 5.3 и выше
- Для Laravel 5 до 5.2
- Для Laravel 4 (старый ответ)
- Для Laravel 3 (даже более старый ответ)
- Laravel >= 5.3
- Изменить новый редиректор авторизации промежуточного ПО
- TL; описание DR
- Laravel 3
- Laravel 5.2
Для Laravel 5.3 и выше
Отметьте ответ Скотта ниже.
Для Laravel 5 до 5.2
Проще говоря,
В промежуточном ПО auth:
// redirect the user to «/login» // and stores the url being accessed on session if (Auth::guest()) { return redirect()->guest(‘login’); } return $next($request);
Действие входа:
// redirect the user back to the intended page // or defaultpage if there isn’t one if (Auth::attempt([’email’ => $email, ‘password’ => $password])) { return redirect()->intended(‘defaultpage’); }
Для Laravel 4 (старый ответ)
Во время этого ответа официальной поддержки со стороны самой структуры не было. В настоящее время вы можете использовать метод, указанный bgdrl ниже. Этот метод: (я пробовал обновить его ответ, но, похоже, он не примет)
В режиме фильтра auth:
// redirect the user to «/login» // and stores the url being accessed on session Route::filter(‘auth’, function() { if (Auth::guest()) { return Redirect::guest(‘login’); } });
Действие входа:
// redirect the user back to the intended page // or defaultpage if there isn’t one if (Auth::attempt([’email’ => $email, ‘password’ => $password])) { return Redirect::intended(‘defaultpage’); }
Для Laravel 3 (даже более старый ответ)
Вы можете реализовать его следующим образом:
Route::filter(‘auth’, function() { // If there no user authenticated session if (Auth::guest()) { // Stores current url on session and redirect to login page Session::put(‘redirect’, URL::full()); return Redirect::to(‘/login’); } if ($redirect = Session::get(‘redirect’)) { Session::forget(‘redirect’); return Redirect::to($redirect); } }); // on controller public function get_login() { $this->layout->nest(‘content’, ‘auth.login’); } public function post_login() { $credentials = [ ‘username’ => Input::get(’email’), ‘password’ => Input::get(‘password’) ]; if (Auth::attempt($credentials)) { return Redirect::to(‘logged_in_homepage_here’); } return Redirect::to(‘login’)->with_input(); }
Сохранение перенаправления на сеансе имеет преимущество в том, что он сохраняется, даже если пользователь пропустил ввод своих учетных данных или у него нет учетной записи и он должен зарегистрироваться.
Это также позволяет любому другому, кроме Auth, устанавливать перенаправление на сеанс, и он будет работать волшебным образом.
Ответ №1
Laravel >= 5.3
Изменения Auth в 5.3 делают реализацию этого немного проще и немного отличаются от 5.2, поскольку промежуточное ПО Auth было перенесено в контейнер службы.
Изменить новый редиректор авторизации промежуточного ПО
/app/Http/Middleware/RedirectIfAuthenticated.php
Измените функцию дескриптора, так что она выглядит так:
public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { return redirect()->intended(‘/home’); } return $next($request); }
TL; описание DR
Единственная разница в 4-й строке; по умолчанию он выглядит так:
return redirect(«/home»);
Так как Laravel >= 5.3 автоматически сохраняет последний “намеченный” маршрут при проверке Auth Guard, он изменяется на:
return redirect()->intended(‘/home’);
Это означает, что Laravel перенаправляет на последнюю предполагаемую страницу перед входом в систему, иначе перейдите в “/home” или туда, куда вы хотите отправить их по умолчанию.
Надеюсь, это поможет кому-то другому – там не так много различий между 5.2 и 5.3, и в этой области, в частности, их довольно много.
Ответ №2
Я нашел эти два замечательных метода, которые могут быть очень полезны для вас.
Redirect::guest(); Redirect::intended();
Вы можете применить этот фильтр к маршрутам, которым требуется аутентификация.
Route::filter(‘auth’, function() { if (Auth::guest()) { return Redirect::guest(‘login’); } });
Что этот метод в основном делает для хранения страницы, которую вы пытались посетить, и перенаправляет вас на страницу входа.
Когда пользователь аутентифицирован, вы можете позвонить
return Redirect::intended();
и он перенаправляет вас на страницу, которую вы пытались достичь вначале.
Это отличный способ сделать это, хотя я обычно использую метод ниже.
Redirect::back()
Вы можете проверить этот удивительный блог.
Ответ №3
Вы можете использовать Перенаправление:: предназначенную функцию. Он перенаправляет пользователя на URL-адрес, к которому они пытались получить доступ, прежде чем его поймает фильтр подлинности. Резервный URI может быть присвоен этому
метод в случае, если предполагаемая судьба недоступна.
In post login/register:
return Redirect::intended(‘defaultpageafterlogin’); Ответ №4
Я использую это некоторое время на моем кодексе выбора языка. До тех пор, пока вам нужно вернуться всего на одну страницу, он отлично работает:
return Redirect::to(URL::previous());
Это не самое мощное решение, но оно очень простое и может помочь решить несколько головоломок.:)
Ответ №5return Redirect::intended(‘/’);
это перенаправит вас на страницу по умолчанию вашего проекта, то есть на стартовую страницу.
Ответ №6
Измените конструктор LoginControllers на:
public function __construct() { session([‘url.intended’ => url()->previous()]); $this->redirectTo = session()->get(‘url.intended’); $this->middleware(‘guest’)->except(‘logout’); }
Он перенаправит вас обратно на страницу до страницы входа (2 страницы назад).
Ответ №7
Для laravel 5. * попробуйте эти.
return redirect()->intended(‘/’);
или
return Redirect::intended(‘/’); Ответ №8
Laravel 3
Я слегка изменил ваш код (Vinícius Fragoso Pinheiro) и поместил следующее в filters.php
Route::filter(‘auth’, function() { // If there no user authenticated session if (Auth::guest()) { // Flash current url to session and redirect to login page Session::flash(‘redirect’, URL::full()); return Redirect::guest(‘login’); } });
И затем в моем AuthController.php:
// Try to log the user in. if (Auth::attempt($userdata)) { if ($redirect = Session::get(‘redirect’)) { return Redirect::to($redirect); } else { // Redirect to homepage return Redirect::to(‘your_default_logged_in_page’)->with(‘success’, ‘You have logged in successfully’); } } else { // Reflash the session data in case we are in the middle of a redirect Session::reflash(‘redirect’); // Redirect to the login page. return Redirect::to(‘login’)->withErrors([‘password’ => ‘Password invalid’])->withInput(Input::except(‘password’)); }
Обратите внимание, что данные сеанса ‘redirect’ помечены, если есть проблема с аутентификацией. Это сохраняет целостность перенаправления во время любых неудачных попыток входа в систему, но если пользователь щелкнет в любой момент, следующий процесс входа не будет нарушен данными сеанса.
Вам также нужно перепроверить данные в момент отображения формы входа в AuthController, иначе цепочка будет нарушена:
public function showLogin() { // Reflash the session data in case we are in the middle of a redirect Session::reflash(‘redirect’); // Show the login page return View::make(‘auth/login’); } Ответ №9
Используйте Redirect;
Затем используйте это:
return Redirect::back(); Ответ №10
Для Laravel 5.5 и, вероятно, 5.4
В AppHttpMiddlewareRedirectIfAuthenticated измените redirect(‘/home’) на redirect()->intended(‘/home’) в функции дескриптора:
public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { return redirect()->intended(‘/home’); } return $next($request); }
в AppHttpControllersAuthLoginController создайте showLoginForm() следующим образом:
public function showLoginForm() { if(!session()->has(‘url.intended’)) { session([‘url.intended’ => url()->previous()]); } return view(‘auth.login’); }
Таким образом, если было намерение для другой страницы, он будет перенаправлять туда, иначе он будет перенаправлять домой.
Ответ №11
Для Laravle 5.7 Вам необходимо внести изменения в:
Промежуточное> RedirectIfAuthenticated.php
Изменить это:
public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { return redirect(‘/admin’); } return $next($request); }
К этому:
public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { return redirect(‘/yourpath’); } return $next($request); }
возврат перенаправления (‘/yourpath’);
Ответ №12
Я использую следующий подход с пользовательским контроллером входа в систему и промежуточным программным обеспечением для Laravel 5.7, но я надеюсь, что это работает в любой из версий laravel 5
-
в промежуточном программном обеспечении
if (Auth::check()){ return $next($request); } else{ return redirect()->guest(route(‘login’)); }
-
метод входа внутри контроллера
if (Auth::attempt([’email’ => $email, ‘password’ => $password])) { return redirect()->intended(‘/default’); }
-
Если вам нужно передать намеренный URL-адрес на стороне клиента, вы можете попробовать следующее
if (Auth::attempt([‘username’ => $request->username, ‘password’ => $request->password])) { $intended_url= redirect()->intended(‘/default’)->getTargetUrl(); $response = array( ‘status’ => ‘success’, ‘redirectUrl’ => $intended_url, ‘message’ => ‘Login successful.you will be redirected to home..’, ); return response()->json($response); } else { $response = array( ‘status’ => ‘failed’, ‘message’ => ‘username or password is incorrect’, ); return response()->json($response); }
Ответ №13
Laravel теперь поддерживает эту функцию “из коробки”! (Я верю с 5.5 или ранее).
Добавьте __construct() к вашему Controller как показано ниже:
public function __construct() { $this->middleware(‘auth’); }
После входа ваши пользователи будут перенаправлены на страницу, которую они изначально хотели посетить.
Вы также можете добавить функцию проверки электронной почты Laravel, как того требует логика вашего приложения:
public function __construct() { $this->middleware(‘auth’); $this->middleware(‘verified’); }
Документация содержит очень краткий пример:
Бонус: также можно выбрать, к каким методам контроллера применяется промежуточное программное обеспечение, используя параметры except или only.
Пример с except:
public function __construct() { $this->middleware(‘auth’, [‘except’ => [‘index’, ‘show’]]); }
Пример only:
public function __construct() { $this->middleware(‘auth’, [‘only’ => [‘index’, ‘show’]]); }
Более подробная информация о except и only вариантах промежуточного уровня:
Ответ №14
Пробовал ли вы это на своих маршрутах .php?
Route::group([‘middleware’ => [‘web’]], function () { // Route::get(‘/’,’HomeController@index’); }); Ответ №15 // Also place this code into base controller in contract function, because ever controller extends base controller if(Auth::id) { //here redirect your code or function } if (Auth::guest()) { return Redirect::guest(‘login’); } Ответ №16
Вот мое решение для 5.1. Мне нужно, чтобы кто-то нажал кнопку “Мне нравится” в сообщении, переадресовывался для входа в систему, а затем возвращался на исходную страницу. Если они уже вошли в систему, кнопка href кнопки “Like” была перехвачена с помощью JavaScript и превращена в запрос AJAX.
Кнопка – это что-то вроде <a href=»/like/931″>Like This Post!</a>. /like/931 обрабатывается с помощью LikeController, который требует промежуточного программного обеспечения auth.
В промежуточном ПО Authenticate (функция handle()) добавьте что-то вроде этого в начале:
if(!str_contains($request->session()->previousUrl(), «/auth/login»)) { $request->session()->put(‘redirectURL’, $request->session()->previousUrl()); $request->session()->save(); }
Измените /auth/login на то, что ваш URL для входа. Этот код сохраняет исходный URL-адрес страницы в сеансе, если URL-адрес не является URL-адресом входа. Это необходимо, потому что похоже, что это промежуточное программное обеспечение вызывается дважды. Я не уверен, почему и если это так. Но если вы не проверите это условие, оно будет равно правильной исходной странице, а затем каким-то образом получите значение /auth/login. Возможно, это более элегантный способ сделать это.
Затем в LikeController или любом контроллере, который у вас есть, обрабатывается URL-адрес кнопки, нажатой на исходную страницу:
//some code here that adds a like to the database //… return redirect($request->session()->get(‘redirectURL’));
Этот метод супер прост, не требует переопределения любых существующих функций и отлично работает. Возможно, для Laravel есть более простой способ сделать это, но я не уверен, что это такое. Использование функции intended() не работает в моем случае, потому что LikeController также должен знать, что предыдущий URL должен был перенаправить обратно. По существу, два уровня перенаправления назад.
Ответ №17
Для Laravel 5.2 (предыдущие версии я не использовал)
Вставьте код в файл-приложениеHttpControllersAuthAurhController.php
/** * Overrides method in class ‘AuthenticatesUsers’ * * @return IlluminateContractsViewFactory|IlluminateViewView */ public function showLoginForm() { $view = property_exists($this, ‘loginView’) ? $this->loginView : ‘auth.authenticate’; if (view()->exists($view)) { return view($view); } /** * seve the previous page in the session */ $previous_url = Session::get(‘_previous.url’); $ref = isset($_SERVER[‘HTTP_REFERER’]) ? $_SERVER[‘HTTP_REFERER’] : »; $ref = rtrim($ref, ‘/’); if ($previous_url != url(‘login’)) { Session::put(‘referrer’, $ref); if ($previous_url == $ref) { Session::put(‘url.intended’, $ref); } } /** * seve the previous page in the session * end */ return view(‘auth.login’); } /** * Overrides method in class ‘AuthenticatesUsers’ * * @param Request $request * @param $throttles * * @return IlluminateHttpRedirectResponse */ protected function handleUserWasAuthenticated(Request $request, $throttles) { if ($throttles) { $this->clearLoginAttempts($request); } if (method_exists($this, ‘authenticated’)) { return $this->authenticated($request, Auth::guard($this->getGuard())->user()); } /*return to the previous page*/ return redirect()->intended(Session::pull(‘referrer’)); /*return redirect()->intended($this->redirectPath()); /*Larevel default*/ }
И пространство имён импорта: use Session;
Если вы не внесли никаких изменений в файл-приложениеHttpControllersAuthAurhController.php, вы можете просто заменить его файлом из GitHub
Ответ №18
Laravel 5.2
Если вы используете другое промежуточное ПО, например Admin, вы можете установить сеанс для url.intended, используя следующее:
В основном нам нужно установить вручную Session::put(‘url.intended’, URL::full()); для перенаправления.
Пример
if (Auth::guard($guard)->guest()) { if ($request->ajax() || $request->wantsJson()) { return response(‘Unauthorized.’, 401); } else { Session::put(‘url.intended’, URL::full()); return redirect(‘login’); } }
При попытке входа в систему
Убедитесь, что при попытке входа в систему использовать return Redirect::intended(‘default_path’);
Ответ №19
Larvel 5.3, это действительно сработало для меня, просто обновив LoginController.php
use IlluminateSupportFacadesSession; use IlluminateSupportFacadesURL; public function __construct() { $this->middleware(‘guest’, [‘except’ => ‘logout’]); Session::set(‘backUrl’, URL::previous()); } public function redirectTo() { return Session::get(‘backUrl’) ? Session::get(‘backUrl’) : $this->redirectTo; }
ref: https://laracasts.com/discuss/channels/laravel/redirect-to-previous-page-after-login