Laravel redirect kembali ke tujuan semula setelah login

189

Ini sepertinya aliran yang sangat mendasar, dan Laravelmemiliki begitu banyak solusi bagus untuk hal-hal dasar, saya merasa seperti kehilangan sesuatu.

Seorang pengguna mengklik tautan yang membutuhkan otentikasi. LARAVEL ini auth tendangan filter dan rute mereka ke halaman login. Pengguna masuk, lalu pergi ke halaman asli yang mereka coba buka sebelum filter 'auth' masuk.

Apakah ada cara yang baik untuk mengetahui halaman apa yang mereka coba dapatkan pada awalnya? Karena Laravel adalah orang yang mencegat permintaan, saya tidak tahu apakah itu melacak di suatu tempat untuk perutean yang mudah setelah pengguna masuk.

Jika tidak, saya ingin tahu bagaimana beberapa dari Anda telah menerapkan ini secara manual.

JOV
sumber

Jawaban:

234

Untuk Laravel 5.3 ke atas

Periksa jawaban Scott di bawah ini.

Untuk Laravel 5 hingga 5.2

Sederhananya,

Pada middleware auth:

// redirect the user to "/login"
// and stores the url being accessed on session
if (Auth::guest()) {
    return redirect()->guest('login');
}
return $next($request);

Saat aksi masuk:

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

Untuk Laravel 4 (jawaban lama)

Pada saat jawaban ini tidak ada dukungan resmi dari kerangka itu sendiri. Saat ini Anda dapat menggunakannyametode yang ditunjukkan oleh bgdrl di bawah inimetode ini: (Saya sudah mencoba memperbarui jawabannya, tetapi sepertinya dia tidak akan menerima)

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

Saat aksi masuk:

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

Untuk Laravel 3 (jawaban yang lebih lama)

Anda bisa menerapkannya seperti ini:

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

Menyimpan pengalihan pada Sesi memiliki manfaat bertahan meskipun pengguna tidak mengetik kredensial atau dia tidak memiliki akun dan harus mendaftar.

Ini juga memungkinkan hal lain selain Auth untuk mengatur pengalihan pada sesi dan itu akan bekerja secara ajaib.

vFragosop
sumber
Bukankah lebih masuk akal untuk beralih ke sesi daripada menaruh dan melupakan? Tindakan masuk Anda hanya akan mengembalikan pengalihan ke nilai di sesi jika ada atau halaman default sebaliknya.
bilalq
2
Saya telah mengedit jawaban untuk menjelaskan mengapa ini lebih baik daripada flash.
vFragosop
Itu masuk akal. Lebih baik daripada memercikkan setiap kali.
bilalq
1
Ketika Auth :: upaya () lewat, Anda bisa mengarahkan pengguna ke halaman default (biasanya rumahnya). Pengalihan itu akan melewati filter itu lagi dan itu akan mengarahkannya ke URL yang diminta asli jika ada. Kalau tidak, itu hanya akan terus memberikan rumahnya. Saya akan memberikan contoh tindakan login.
vFragosop
1
di 5.1 ada di middleware RedirectIfAuthenticated.php: if ($ this-> auth-> check ()) {return redirect ('/ privatepage'); }
Dave Driesmans
73

Laravel> = 5.3

Perubahan Auth di 5.3 membuat implementasi ini sedikit lebih mudah, dan sedikit berbeda dari 5.2 karena Auth Middleware telah dipindahkan ke wadah layanan.

Ubah pengalihan autor Middleware baru

/app/Http/Middleware/RedirectIfAuthenticated.php

Ubah sedikit fungsi pegangan, sehingga terlihat seperti:

public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->check()) {
        return redirect()->intended('/home');
    }

    return $next($request);
}

TL; penjelasan DR

Satu-satunya perbedaan adalah di baris ke-4; secara default tampilannya seperti ini:

return redirect("/home");

Karena Laravel> = 5.3 secara otomatis menyimpan rute "yang dimaksudkan" terakhir ketika memeriksa Auth Guard, itu berubah menjadi:

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

Itu memberitahu Laravel untuk mengarahkan ulang ke halaman yang dituju sebelum masuk, jika tidak pergi ke "/ home" atau ke mana pun Anda ingin mengirimnya secara default.

Semoga ini bisa membantu orang lain - tidak banyak perbedaan antara 5,2 dan 5,3, dan di bidang ini khususnya ada beberapa.

Scott Byers
sumber
2
untuk Laravel 6.4 ini tidak berfungsi lagi ... ada ide, mohon?
alex toader
Saya akan gunakan return redirect()->intended(RouteServiceProvider::HOME);untuk menjaga jalur rumah Anda di satu tempat.
Mateusz
26

Saya menemukan dua metode hebat yang mungkin sangat membantu Anda.

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

Anda dapat menerapkan filter ini ke rute yang perlu otentikasi.

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

Apa metode ini pada dasarnya adalah untuk menyimpan halaman yang Anda coba kunjungi dan itu mengarahkan Anda ke halaman login .

Ketika pengguna diautentikasi, Anda dapat menelepon

return Redirect::intended();

dan itu akan mengarahkan Anda ke halaman yang Anda coba jangkau pada awalnya.

Ini cara yang bagus untuk melakukannya walaupun saya biasanya menggunakan metode di bawah ini.

Redirect::back()

Anda dapat memeriksa blog yang luar biasa ini .

Giannis christofakis
sumber
Ini jauh lebih baik daripada solusi di atas. Solusi di atas membutuhkan kemampuan untuk menutup fungsi login yang tidak dapat saya lakukan dengan 4.1. Tapi ini jauh lebih sederhana dan berhasil.
user2662680
20

Anda dapat menggunakan fungsi Redirect :: yang dimaksudkan . Ini akan mengarahkan pengguna ke URL yang mereka coba akses sebelum ditangkap oleh filter autentik. URI mundur dapat diberikan untuk metode ini jika takdir tujuan yang dimaksud tidak tersedia.

Di pos masuk / daftar:

return Redirect::intended('defaultpageafterlogin');
dabuno
sumber
11

Saya telah menggunakan ini untuk sementara waktu pada kode pemilih bahasa saya. Selama Anda hanya perlu kembali dengan hanya 1 halaman berfungsi dengan baik:

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

Ini bukan solusi yang paling kuat di luar sana tetapi sangat mudah dan dapat membantu memecahkan beberapa teka-teki. :)

Federico Stango
sumber
5
Ya sebelumnya () berfungsi dengan baik. Tetapi jika upaya login pertama Anda gagal (jadi halaman 'login gagal' menjadi halaman Anda sebelumnya) dan upaya login kedua berhasil maka Anda akan diarahkan ke halaman login lagi (yang dapat mengarahkan Anda ke halaman utama).
Shriganesh Shintre
11

Ubah konstruktor LoginControllers Anda menjadi:

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

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

Ini akan mengarahkan Anda kembali ke halaman SEBELUM halaman login (2 halaman kembali).

MevlütÖzdemir
sumber
Satu-satunya yang bekerja untukku. Itu berarti saya memiliki pengalihan lain yang terjadi di suatu tempat tetapi siapa yang tahu di mana.
Arthur Tarasov
8
return Redirect::intended('/');

ini akan mengarahkan Anda ke halaman default proyek Anda yaitu halaman awal.

Parag Bhingre
sumber
6

Untuk laravel 5. * coba ini.

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

atau

return Redirect::intended('/');
Nuruzzaman Milon
sumber
5

Laravel 3

Saya mengubah sedikit kode (Vinícius Fragoso Pinheiro) Anda sedikit, dan menempatkan yang berikut ini di 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');
    }
});

Dan kemudian di dalam AuthController.php saya:

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

Perhatikan bahwa 'redirect'data sesi direfleksikan jika ada masalah otentikasi. Ini menjaga pengalihan tetap utuh selama kecelakaan login, tetapi jika pengguna mengklik pada titik mana pun, proses login berikutnya tidak terganggu oleh data sesi.

Anda juga perlu mem-reflash data pada titik yang menunjukkan formulir login di Anda AuthController, jika tidak rantai rusak:

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');
}
Joe Richards
sumber
3

Menggunakan Redirect;

Kemudian gunakan ini:

return Redirect::back();
ujwal dhakal
sumber
0

Larvel 5.3 ini benar-benar bekerja untuk saya dengan hanya memperbarui 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

Nomi
sumber
0

Untuk Laravel 5.5 dan mungkin 5.4

Di App \ Http \ Middleware \ RedirectIfAuthenticated, ubah redirect('/home')ke redirect()->intended('/home')dalam fungsi pegangan:

public function handle($request, Closure $next, $guard = null)
{
    if (Auth::guard($guard)->check()) {
        return redirect()->intended('/home');
    }

    return $next($request);
}

di App \ Http \ Controllers \ Auth \ LoginController membuat showLoginForm()fungsi sebagai berikut:

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

Dengan cara ini jika ada maksud untuk halaman lain maka akan dialihkan ke sana jika tidak maka akan mengarahkan pulang.

DerDare
sumber
0

Saya menggunakan pendekatan berikut dengan pengontrol login kustom dan middleware untuk Laravel 5.7, tapi saya harap itu berfungsi di salah satu dari versi laravel 5

  • di dalam middleware

    if (Auth::check()){
        return $next($request);
    }
    else{
      return redirect()->guest(route('login'));
    }
  • metode login pengendali dalam

    if (Auth::attempt(['email' => $email, 'password' => $password])) {
    return redirect()->intended('/default');
    }
  • Jika Anda harus meneruskan URL yang dimaksudkan ke sisi klien , Anda dapat mencoba yang berikut ini

       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);
        }
Nayeem Azad
sumber
0

Pertama, Anda harus tahu, bagaimana Anda mengarahkan pengguna ke rute 'login':

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

Tidak seperti ini:

return redirect()->intended('/signin');
Odilov Oybek
sumber
0

Laravel sekarang mendukung fitur ini di luar kotak! (Saya percaya sejak 5,5 atau sebelumnya).

Tambahkan __construct()metode ke Anda Controllerseperti yang ditunjukkan di bawah ini:

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

Setelah masuk, pengguna Anda akan diarahkan ke halaman yang ingin mereka kunjungi pada awalnya.

Anda juga dapat menambahkan fitur verifikasi email Laravel seperti yang dipersyaratkan oleh logika aplikasi Anda:

public function __construct()
{
    $this->middleware(['auth', 'verified']);
}

Dokumentasi berisi contoh yang sangat singkat:

Mungkin juga untuk memilih metode pengontrol mana middleware berlaku dengan menggunakan except atau onlyopsi.

Contoh dengan except:

public function __construct()
{
    $this->middleware('auth', ['except' => ['index', 'show']]);
}

Contoh dengan only:

public function __construct()
{
    $this->middleware('auth', ['only' => ['index', 'show']]);
}

Informasi lebih lanjut tentang exceptdan onlyopsi middleware:

LobsterBaz
sumber
0

jika Anda menggunakan axios atau pustaka javascript AJAX lainnya, Anda mungkin ingin membuka kembali url dan meneruskan ke ujung depan

Anda dapat melakukannya dengan kode di bawah ini

   $default = '/';

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

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

Ini akan mengembalikan string yang diformat json

Emmanuel David
sumber
0

Dalam Laravel 5.8

di App \ Http \ Controllers \ Auth \ LoginController tambahkan metode berikut

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

di App \ Http \ Middleware \ RedirectIfAuthenticated, ganti "return redirect ('/ home');" dengan yang berikut ini

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

Apakah Anda mencoba ini di routes.php Anda?

Route::group(['middleware' => ['web']], function () {
    //
    Route::get('/','HomeController@index');
});
Arios
sumber
-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');
}
programmer keren
sumber
2
Berikan komentar untuk mengikuti kode Anda untuk memberikan beberapa konteks. Terima kasih
Suever
-1

Ini solusi saya untuk 5.1. Saya membutuhkan seseorang untuk mengklik tombol "Suka" pada posting, diarahkan untuk login, lalu kembali ke halaman asli. Jika sudah masuk, tombol href"Suka" dicegat dengan JavaScript dan diubah menjadi permintaan AJAX.

Tombolnya seperti <a href="https://stackoverflow.com/like/931">Like This Post!</a>. /like/931ditangani oleh LikeController yang membutuhkan authmiddleware.

Di middleware Otentikasi ( handle()fungsi), tambahkan sesuatu seperti ini di awal:

    if(!str_contains($request->session()->previousUrl(), "/auth/login")) {
        $request->session()->put('redirectURL', $request->session()->previousUrl());
        $request->session()->save();
    }

Ubah /auth/loginke apa pun URL Anda untuk masuk. Kode ini menyimpan URL halaman asli dalam sesi kecuali URL adalah URL login. Ini diperlukan karena tampaknya seolah-olah middleware ini dipanggil dua kali. Saya tidak yakin mengapa atau apakah itu benar. Tetapi jika Anda tidak memeriksa persyaratan itu, itu akan sama dengan halaman asli yang benar, dan kemudian entah bagaimana kebetulan/auth/login . Mungkin ada cara yang lebih elegan untuk melakukan ini.

Kemudian, di LikeControlleratau pengontrol apa pun yang Anda miliki yang menangani URL untuk tombol yang ditekan pada halaman asli:

//some code here that adds a like to the database
//...
return redirect($request->session()->get('redirectURL'));

Metode ini sangat sederhana, tidak perlu mengabaikan fungsi apa pun yang ada, dan berfungsi dengan baik. Mungkin ada beberapa cara yang lebih mudah bagi Laravel untuk melakukan ini, tetapi saya tidak yakin apa itu. Menggunakan intended()fungsi tidak berfungsi dalam kasus saya karena LikeController perlu juga tahu apa URL sebelumnya untuk mengarahkan kembali ke sana. Pada dasarnya dua tingkat pengalihan ke belakang.

Brynn Bateman
sumber
-1

Untuk Laravel 5.2 (versi sebelumnya saya tidak menggunakan)

Rekatkan kode ke aplikasi file \ 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*/
}

Dan impor namespace: use Session;

Jika Anda belum membuat perubahan apa pun pada aplikasi file \ Http \ Controllers \ Auth \ AurhController.php, Anda bisa menggantinya dengan file dari GitHub

zdorovo
sumber
-1

Laravel 5.2

Jika Anda menggunakan Middleware lain seperti Admin middleware, Anda dapat mengatur sesi untuk url. Disengaja dengan menggunakan berikut ini:

Pada dasarnya kita perlu mengatur secara manual \Session::put('url.intended', \URL::full());untuk pengalihan.

Contoh

  if (\Auth::guard($guard)->guest()) {
      if ($request->ajax() || $request->wantsJson()) {
         return response('Unauthorized.', 401);
      } else {
        \Session::put('url.intended', \URL::full());
        return redirect('login');
      }
  }

Saat mencoba masuk

Pastikan untuk menggunakan upaya login return \Redirect::intended('default_path');

Rashedul Islam Sagor
sumber
Itu untuk apa redirect()->guest('login').
Emile Bergeron
-1

Untuk Laravle 5.7, Anda perlu mengubahnya menjadi:

Middleware> RedirectIfAuthenticated.php

Ubah ini:

public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/admin');
        }

        return $next($request);
    }

Untuk ini:

public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
            return redirect('/yourpath');
        }

        return $next($request);
    }

return redirect ('/ yourpath');

Pangeran Ahmed
sumber
Apa mypath? (pass pengguna untuk kembali ke ini)
Mostafa Norzade