Laravel перенаправляет обратно в исходное место после входа в систему

Это похоже на довольно простой поток, и Laravel имеет так много хороших решений для основных вещей, я чувствую, что что-то не хватает.

Пользователь нажимает ссылку, требующую аутентификации. Фильтр авторизации Laravel запускается и направляет их на страницу входа. Пользователь входит в систему, затем переходит на исходную страницу, к которой они пытались добраться, прежде чем выйдет фильтр "auth".

Есть ли хороший способ узнать, на какой странице они пытались добраться до изначально? Поскольку Laravel - это тот, кто перехватывает запрос, я не знал, отслеживает ли он где-нибудь удобную маршрутизацию после входа пользователя в систему.

Если нет, мне было бы интересно узнать, как некоторые из вас выполнили это вручную.

Ответ 1

Для 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, устанавливать перенаправление на сеанс, и он будет работать волшебным образом.

Ответ 2

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, и в этой области, в частности, их довольно много.

Ответ 3

Я нашел эти два замечательных метода, которые могут быть очень полезны для вас.

Redirect::guest();
Redirect::intended();

Вы можете применить этот фильтр к маршрутам, которым требуется аутентификация.

Route::filter('auth', function()
{
    if (Auth::guest()) {
           return Redirect::guest('login');
    }
});

Что этот метод в основном делает для хранения страницы, которую вы пытались посетить, и перенаправляет вас на страницу входа.

Когда пользователь аутентифицирован, вы можете позвонить

return Redirect::intended();

и он перенаправляет вас на страницу, которую вы пытались достичь вначале.

Это отличный способ сделать это, хотя я обычно использую метод ниже.

Redirect::back()

Вы можете проверить этот удивительный блог.

Ответ 4

Вы можете использовать Перенаправление:: предназначенную функцию. Он перенаправляет пользователя на URL-адрес, к которому они пытались получить доступ, прежде чем его поймает фильтр подлинности. Резервный URI может быть присвоен этому метод в случае, если предполагаемая судьба недоступна.

In post login/register:

return Redirect::intended('defaultpageafterlogin');

Ответ 5

Я использую это некоторое время на моем кодексе выбора языка. До тех пор, пока вам нужно вернуться всего на одну страницу, он отлично работает:

return Redirect::to(URL::previous());

Это не самое мощное решение, но оно очень простое и может помочь решить несколько головоломок.:)

Ответ 6

return Redirect::intended('/');

это перенаправит вас на страницу по умолчанию вашего проекта, то есть на стартовую страницу.

Ответ 7

Измените конструктор LoginControllers на:

public function __construct()
    {
        session(['url.intended' => url()->previous()]);
        $this->redirectTo = session()->get('url.intended');

        $this->middleware('guest')->except('logout');
    }

Он перенаправит вас обратно на страницу до страницы входа (2 страницы назад).

Ответ 8

Для laravel 5. * попробуйте эти.

return redirect()->intended('/');

или

return Redirect::intended('/');

Ответ 9

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');
}

Ответ 10

Используйте Redirect;

Затем используйте это:

return Redirect::back();

Ответ 11

Для 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');
}

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

Ответ 12

Для 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');

Ответ 13

Я использую следующий подход с пользовательским контроллером входа в систему и промежуточным программным обеспечением для 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);
        }
    

Ответ 14

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 вариантах промежуточного уровня:

Ответ 15

Пробовал ли вы это на своих маршрутах .php?

Route::group(['middleware' => ['web']], function () {
    //
    Route::get('/','[email protected]');
});

Ответ 16

       // 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');
}

Ответ 17

Вот мое решение для 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 должен был перенаправить обратно. По существу, два уровня перенаправления назад.

Ответ 18

Для 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

Ответ 19

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');

Ответ 20

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