Feđa
Feđa

Reputation: 49

Redirect after authentication in Laravel 5

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

Answers (5)

Laravel 5.2

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

For Laravel 5.0 (only what is different)

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

Mark Rady
Mark Rady

Reputation: 1

Try:

redirect()->intended();

Upvotes: 0

Josh
Josh

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

Giedrius Kiršys
Giedrius Kiršys

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

Muihlinn
Muihlinn

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

Related Questions