Після входу в Laravel переадресація повертається до початкового місця призначення


189

Це здається досить базовим потоком і Laravelмає стільки приємних рішень для основних речей, я відчуваю, що мені щось не вистачає.

Користувач натискає посилання, яке вимагає автентифікації. Авторизований фільтр Ларавеля починається та спрямовує їх на сторінку входу. Користувач входить у систему, потім переходить на оригінальну сторінку, на яку намагалися потрапити, перш ніж увійшов фільтр "auth".

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

Якщо ні, мені було б цікаво почути, як деякі з вас реалізували це вручну.

Відповіді:


234

Для Laravel 5.3 і вище

Перевірте відповідь Скотта нижче.

Для Laravel 5 до 5,2

Простіше кажучи,

На аутентичному програмному забезпеченні:

// 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 нижчецей метод: (Я намагався оновити його відповідь, але, схоже, він не прийме)

На аут-фільтрі:

// 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's 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, встановити переспрямування на сеанс, і це буде працювати магічно.


Хіба не було б більше сенсу прошивати сеанс, а не ставити і забувати? Ваша дія входу просто поверне переспрямування до значення в сеансі, якщо воно існує або сторінка за замовчуванням інша.
bilalq

2
Я відредагував відповідь, щоб пояснити, чому це краще, ніж спалах.
vFragosop

Що має сенс. Краще, ніж перепрошивати кожен раз.
bilalq

1
Коли Auth :: спроба () пройде, ви можете просто перенаправити користувача на сторінку за замовчуванням (зазвичай на його домашню сторінку). Це переадресація знову пройде через цей фільтр, і він перенаправить його на оригінальну запитувану URL-адресу, якщо така є. Інакше він просто продовжить надавати його будинок. Я наведу приклад дії входу.
vFragosop

1
в 5.1 - у середньому програмному забезпеченні RedirectIfAuthentication.php: if ($ this-> auth-> check ()) {return redirect ('/ private page'); }
Дейв Дрісманс

73

Ларавель> = 5,3

Зміни Auth в 5.3 роблять реалізацію цього дещо простішою і трохи іншою, ніж 5.2, оскільки Auth Middleware переміщено в контейнер служб.

Змініть новий перенаправник автентичного програмного забезпечення Middleware

/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
для Laravel 6.4 це вже не працює ... будь-яка ідея pls?
alex toader

Я хотів return redirect()->intended(RouteServiceProvider::HOME);би зберегти ваш домашній шлях в одному місці.
Матеуш

26

Я знайшов ті два чудових методу, які можуть вам дуже допомогти.

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

Ви можете застосувати цей фільтр до маршрутів, які потребують аутентифікації.

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

В основному цей метод робить це зберігання сторінки, яку ви намагалися відвідати, і він перенаправляє вас на сторінку входу .

Після автентифікації користувача ви можете зателефонувати

return Redirect::intended();

і він переспрямовує вас на сторінку, до якої ви намагалися зайти спочатку.

Це чудовий спосіб зробити це, хоча я зазвичай використовую наведений нижче метод.

Redirect::back()

Ви можете перевірити цей дивовижний блог.


Це набагато краще, ніж рішення вище. Вищезазначені рішення вимагають можливості передати закриття функції входу, що я не міг зробити з 4.1. Але це було набагато простіше і працювало так, як є.
користувач2662680

20

Ви можете використовувати функцію Redirect :: за призначенням . Він переспрямовує користувача до URL-адреси, до якої він намагався отримати доступ, перш ніж потрапив у фільтр автентичних даних. Цьому методу може бути наданий резервний URI, якщо призначений дезінатон недоступний.

У вхід / реєстрація після публікації:

return Redirect::intended('defaultpageafterlogin');

11

Я використовую це деякий час у моєму коді вибору мови. Поки вам потрібно повернутися лише на 1 сторінці, це добре працює:

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

Це не найпотужніше рішення, але це дуже просто і може допомогти вирішити кілька загадок. :)


5
Так, попередній () працює чудово. Але якщо ваше перше зусилля для входу не вдається (тому сторінка "реєстрація не вдалася" стає вашою попередньою сторінкою), а зусилля з другим входом вдаються, ви перенаправляєтесь на сторінку входу знову (що може перенаправити вас на домашню сторінку).
Шріганеш Шінтре

11

Змініть свій конструктор LoginControllers на:

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

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

Він перенаправить вас назад на сторінку, перш ніж перейти на сторінку входу (2 сторінки назад).


Єдиний, хто працює на мене. Це повинно означати, що я десь переспрямовує десь, але хто знає куди.
Артур Тарасов

8
return Redirect::intended('/');

це перенаправить вас на сторінку за замовчуванням вашого проекту, тобто на стартову сторінку.



5

Laravel 3

Я трохи підмітив ваш (Vinícius Fragoso Pinheiro) код і помістив у filter.php наступне

Route::filter('auth', function()
{
    // If there's 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');
}

3

Використовуйте Redirect;

Потім скористайтеся цим:

return Redirect::back();

0

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

посилання: https://laracasts.com/discuss/channels/laravel/redirect-to-previous-page-after-login


0

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

у додатку \ Http \ Контролери \ Auth \ LoginController створіть showLoginForm()функцію так:

public function showLoginForm()
{
    if(!session()->has('url.intended'))
    {
        session(['url.intended' => url()->previous()]);
    }
    return view('auth.login');
}

Таким чином, якщо був намір на іншу сторінку, вона буде перенаправлена ​​туди, інакше перенаправить на домашню сторінку.


0

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

0

По-перше, ви повинні знати, як ви перенаправляєте користувача на "вхід" на маршрут:

return redirect()->guest('/signin');

Не так:

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

0

Тепер Laravel підтримує цю функцію нестандартно! (Я вірю з 5.5 або раніше).

Додайте __construct()метод до свого, Controllerяк показано нижче:

public function __construct()
{
    $this->middleware('auth');
}

Після входу ваші користувачі будуть перенаправлені на сторінку, яку вони мали намір відвідати спочатку.

Ви також можете додати функцію підтвердження електронної пошти Laravel відповідно до логіки програми:

public function __construct()
{
    $this->middleware(['auth', '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 параметри програмне забезпечення середнього програмного забезпечення:


0

якщо ви використовуєте axios або іншу бібліотеку JavaScript AJAX, можливо, ви захочете отримати URL-адресу та перейти до переднього кінця

це можна зробити за допомогою наведеного нижче коду

   $default = '/';

   $location = $request->session()->pull('url.intended', $default);

    return ['status' => 200, 'location' => $location];

Це поверне рядок у форматі json


0

У Ларавелі 5.8

у додатку \ Http \ Контролери \ Auth \ LoginController додайте наступний метод

public function showLoginForm()
{
    if(!session()->has('url.intended'))
        {
            session(['url.intended' => url()->previous()]);
        }
    return view('auth.login');
}

у додатку \ Http \ Middleware \ RedirectIfAuthentication замініть "return redirect ('/ home"); "на наступне

 if (Auth::guard($guard)->check()) 
    {
        return redirect()->intended();
    }

-1

Ви пробували це у своєму route.php?

Route::group(['middleware' => ['web']], function () {
    //
    Route::get('/','HomeController@index');
});

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

2
Будь ласка, вкажіть коментар, щоб увійти до свого коду, щоб вказати контекст. Спасибі
Suever

-1

Ось моє рішення для 5.1. Мені потрібно було, щоб хтось натиснув кнопку "Лайк" на публікації, перенаправлявся на вхід, а потім повертався на початкову сторінку. Якщо вони вже ввійшли в систему, кнопку href"Like" перехопили JavaScript і перетворили на запит AJAX.

Кнопка чимось схожа <a href="https://stackoverflow.com/like/931">Like This Post!</a>. /like/931обробляється LikeController, який вимагаєauth проміжного програмного забезпечення.

В аутентифікаційне проміжне програмне забезпечення ( 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-адресою, щоб перенаправити назад на неї. По суті два рівні перенаправлення назад.


-1

Для Laravel 5.2 (попередні версії я не використовував)

Вставте код у файл програми \ Http \ Контролери \ 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


-1

Laravel 5.2

Якщо ви використовуєте інше середнє програмне забезпечення, наприклад, середнє програмне забезпечення адміністратора, ви можете встановити сеанс для 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');


Ось для чого redirect()->guest('login').
Еміль Бержерон

-1

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


Що таке mypath? (користувальницький перехід на це)
Mostafa Norzade
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.