Search code examples
phplaravelhttp-redirectroutesmiddleware

Why is Laravel redirecting to wrong path after login?


I have a Laravel 5.8 project. When I login, it should go to /dashboard. But it goes to http://localhost:8000/img/favicon/favicon.png favicon.png is a resource embedded in app.blade.php. It happens only when I use the auth middleware on route '/dashboard'.

similar problem : Wrong redirection after Login in Laravel, but no solutions. When I use a

file_put_contents("bugfix.log",print_r($request,true));

in Authenticate.php the problem partially solves but memory exhaust error appears when user is logged out and goes to /dashboard.

app/http/middleware/Authenticate.php (the auth middleware) :

<?php

namespace App\Http\Middleware;

use Illuminate\Auth\Middleware\Authenticate as Middleware;

class Authenticate extends Middleware
{
    /**
     * Get the path the user should be redirected to when they are not authenticated.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return string
     */
    protected function redirectTo($request)
    {
        // print_r($request,true);
        // file_put_contents("bugfix.log",print_r($request,true));
        // the above file_put..... code is a strange fix to a problem :
        // i.e. when a user logs in he redirects to http://127.0.0.1:8000/js/es6-promise.map in firefox and http://127.0.0.1:8000/img/favicon/favicon.png in chrome
        if (! $request->expectsJson()) {
            return route('login');
        } 
        return null;
    }
}

routes/web.php

<?php

Auth::routes(['verify' => true ]);

Route::get('/logout-manual', function () {
    request()->session()->invalidate();
});

Route::get('/', 'HomeController@index')->name('home');

Route::get('/tasks', 'TaskController@alltasks')->name('tasks')->middleware('auth');

Route::get('/login/{provider}', 'Auth\SocialAccountController@redirectToProvider');
Route::get('/login/{provider}/callback', 'Auth\SocialAccountController@handleProviderCallback');

Route::get('/dashboard', 'TaskController@alltasks')->middleware('auth');

Route::get('/{any}', 'TaskController@alltasks')->middleware('auth')->where('any', '.*');

app/http/controllers/Auth/LoginController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/dashboard';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}

resources/views/layouts/app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'abc') }}</title>

    <!-- Styles -->
    <link href="{{ asset('css/admin.css') }}" rel="stylesheet">
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">

    <!-- Favicon -->
    <link rel="shortcut icon" href="{{ asset('img/favicon/favicon.png') }}">

    <!-- Icons -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.css" rel="stylesheet">


</head>
    <body class="d-flex flex-column h-100">
        <div id="app" class="flex-shrink-0">
                @yield('content')
        </div>

    <!-- Scripts -->
    <script type="application/javascript" src="{{ asset('js/jquery.min.js') }}"></script>
    <script type="application/javascript" src="{{ asset('js/app.js') }}" defer></script>
    <script type="application/javascript" src="{{ asset('js/abc.js') }}"></script>
    <script type="application/javascript" src="{{ asset('js/bootstrap.bundle.min.js') }}"></script>
</body>
</html>

How can I fix this to go to http://localhost:8000/dashboard instead of http://localhost:8000/img/favicon/favicon.png when a user logs in?


Solution

  • It seems like the intended url is overwritten in the session to /img/favicon/favicon.png. Looking at the provided code I'm thinking that your favicon does not exist at that when it's loaded on your login page it triggers your catch all route.

    This route uses the auth middleware which triggers the intended url to being set. Since your favicon is loaded on your login page it sets the url to that.

    To fix this you could either add the favicon, prefix all routes with e.g./tasks/ or update the regex of the where.

    The example below ensures that the route is not matched when the url starts with /img.

    Route::get('/{any}', 'TaskController@alltasks')->middleware('auth')->where('any', '^(?!img).*');
    

    Personally I'd move all the assets into an assets directory. This way, instead of excluding /img, /css and /js I'd only have to exclude /assets.