Это похоже на довольно простой поток, и Laravel
имеет так много хороших решений для основных вещей, я чувствую, что что-то не хватает.
Пользователь нажимает ссылку, требующую аутентификации. Фильтр авторизации Laravel запускается и направляет их на страницу входа. Пользователь входит в систему, затем переходит на исходную страницу, к которой они пытались добраться, прежде чем выйдет фильтр “auth”.
Есть ли хороший способ узнать, на какой странице они пытались добраться до изначально? Поскольку Laravel – это тот, кто перехватывает запрос, я не знал, отслеживает ли он где-нибудь удобную маршрутизацию после входа пользователя в систему.
Если нет, мне было бы интересно узнать, как некоторые из вас выполнили это вручную.
Для 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, устанавливать перенаправление на сеанс, и он будет работать волшебным образом.
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, и в этой области, в частности, их довольно много.
Я нашел эти два замечательных метода, которые могут быть очень полезны для вас.
Redirect::guest();
Redirect::intended();
Вы можете применить этот фильтр к маршрутам, которым требуется аутентификация.
Route::filter('auth', function()
{
if (Auth::guest()) {
return Redirect::guest('login');
}
});
Что этот метод в основном делает для хранения страницы, которую вы пытались посетить, и перенаправляет вас на страницу входа.
Когда пользователь аутентифицирован, вы можете позвонить
return Redirect::intended();
и он перенаправляет вас на страницу, которую вы пытались достичь вначале.
Это отличный способ сделать это, хотя я обычно использую метод ниже.
Redirect::back()
Вы можете проверить этот удивительный блог.
Вы можете использовать Перенаправление:: предназначенную функцию. Он перенаправляет пользователя на URL-адрес, к которому они пытались получить доступ, прежде чем его поймает фильтр подлинности. Резервный URI может быть присвоен этому
метод в случае, если предполагаемая судьба недоступна.
In post login/register:
return Redirect::intended('defaultpageafterlogin');
Я использую это некоторое время на моем кодексе выбора языка. До тех пор, пока вам нужно вернуться всего на одну страницу, он отлично работает:
return Redirect::to(URL::previous());
Это не самое мощное решение, но оно очень простое и может помочь решить несколько головоломок.:)
return Redirect::intended('/');
это перенаправит вас на страницу по умолчанию вашего проекта, то есть на стартовую страницу.
Измените конструктор LoginControllers на:
public function __construct()
{
session(['url.intended' => url()->previous()]);
$this->redirectTo = session()->get('url.intended');
$this->middleware('guest')->except('logout');
}
Он перенаправит вас обратно на страницу до страницы входа (2 страницы назад).
Для laravel 5. * попробуйте эти.
return redirect()->intended('/');
или
return Redirect::intended('/');
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');
}
Используйте Redirect;
Затем используйте это:
return Redirect::back();
Для Laravel 5.5 и, вероятно, 5.4
В App\Http\Middleware\RedirectIfAuthenticated измените 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);
}
в App\Http\Controllers\Auth\LoginController создайте showLoginForm()
следующим образом:
public function showLoginForm()
{
if(!session()->has('url.intended'))
{
session(['url.intended' => url()->previous()]);
}
return view('auth.login');
}
Таким образом, если было намерение для другой страницы, он будет перенаправлять туда, иначе он будет перенаправлять домой.
Для 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’);
Я использую следующий подход с пользовательским контроллером входа в систему и промежуточным программным обеспечением для 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); }
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
вариантах промежуточного уровня:
Пробовал ли вы это на своих маршрутах .php?
Route::group(['middleware' => ['web']], function () {
//
Route::get('/','HomeController@index');
});
// 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');
}
Вот мое решение для 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 должен был перенаправить обратно. По существу, два уровня перенаправления назад.
Для Laravel 5.2 (предыдущие версии я не использовал)
Вставьте код в файл-приложение\Http\Controllers\Auth\AurhController.php
/**
* Overrides method in class 'AuthenticatesUsers'
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
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 \Illuminate\Http\RedirectResponse
*/
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;
Если вы не внесли никаких изменений в файл-приложение\Http\Controllers\Auth\AurhController.php, вы можете просто заменить его файлом из GitHub
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');
Larvel 5.3, это действительно сработало для меня, просто обновив LoginController.php
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\URL;
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