Reputation: 49
I would like to redirect users back to the page they were viewing before the login page after successful login in Laravel 5. Currently if the user writes a wrong username/password he is redirected to the login page again, with error displayed, and I would like to keep it that way. Also I want this to work when user clicks on login button on a page and also in the situation when user is redirected to login page automatically.
Seems to me that
protected $redirectTo = "/";
is the key thing here, but I don't know how to get it to "redirect to last page which isn't the login page". Any help is appreciated.
Upvotes: 2
Views: 2015
Reputation: 2222
You must store the previous URL when the user enters your login page: https://laravel.com/docs/5.2/helpers#method-url
Session is an option: https://laravel.com/docs/5.2/helpers#method-session
After that you should fill $redirectTo with that information when user tries to login: https://laravel.com/docs/5.2/authentication#included-authenticating
I wrote an example using a Middleware.
First you need to create one:
php artisan make:middleware BeforeLoginForm
Now we need to override the default route for Auth\AuthController@showLoginForm, so we can add our middleware to that route:
app/Http/routes.php
Route::auth();
$this->get('login', 'Auth\AuthController@showLoginForm')
->middleware('before.loginform');
Define an alias for our Middleware:
app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'before.loginform' => \App\Http\Middleware\BeforeLoginForm::class,
];
Our middleware will store the previous URL using the session helper:
app/Http/Middleware/BeforeLoginForm.php
namespace App\Http\Middleware;
use Closure;
class BeforeLoginForm
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
session()->put('before_login_url', url()->previous());
return $next($request);
}
}
The constructor of our AuthController will change the redirectTo property with our previously stored URL:
app/Http/Controllers/Auth/AuthController.php
<?php
namespace App\Http\Controllers\Auth;
class AuthController extends Controller
{
/**
* Where to redirect users after login / registration.
*
* @var string
*/
protected $redirectTo = '/';
/**
* Create a new authentication controller instance.
*
* @return void
*/
public function __construct()
{
$redirectTo = session()->get('before_login_url');
if (!empty($redirectTo)) {
$this->redirectTo = $redirectTo;
}
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
You should register your route like this:
app/Http/routes.php
Route::get('/', 'WelcomeController@index');
Route::get('home', 'HomeController@index');
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
Route::get('auth/login', [
'middleware' => 'before.loginform',
'uses' => 'Auth\AuthController@getLogin'
]);
Then modify redirectTo on your AuthController:
app/Http/Controllers/Auth/AuthController.php
public function __construct(Guard $auth, Registrar $registrar)
{
$this->auth = $auth;
$this->registrar = $registrar;
$redirectTo = session()->get('before_login_url');
if (!empty($redirectTo)) {
$this->redirectTo = $redirectTo;
}
$this->middleware('guest', ['except' => 'getLogout']);
}
I could not test that, will do it later.
Pay attention because the value of the property "redirectTo" will influence not only the authentication but also the registration process.
Upvotes: 0
Reputation: 1804
Laravel allows you to override the redirectPath()
method in the AuthController
which normally will use the redirectTo
property, but you can set it to something dynamic.
public function redirectPath()
{
return request('redirect');
}
And in the login blade template place a hidden input
:
<input type="hidden" name="redirect" value="{{ url()->previous() }}">
Upvotes: 0
Reputation: 5314
$url = URL::previous() != url('login') ? URL::previous() : null;
$previousUrl = old('previousUrl', $url);
Pass $previousUrl
to your login view.
In your login view put previousUrl
field: <input type="hidden" name="previousUrl" value="{{$previousUrl}}"/>
In your AuthController.php
update constructor like that:
public function __construct()
{
$this->redirectTo = app('request')->input('previousUrl') ? : $this->redirectTo;
<...>
}
Not tested, but it should work.
Upvotes: 1
Reputation: 571
use URL::previous() in your redirect or return redirect()->back();
once you know the login was succesful.
Also, you can save the url in the session and use it later at any time.
Upvotes: 0