2

PROBLEM

I'm busy with my first Laravel app and although I see the benefits of the way things are written, I'm having a hard time understanding some of the behaviour.

When I try to login I get redirected to the login page. It seems like the user authenticates correctly, but it redirects to the login page regardless.

WHAT I HAVE

My users table looks like this:

,---------,---------------,---------------,----------------,---------------,-----------,
| user_id | user_username | user_password | user_firtsname | user_lastname | user_type |
|---------|---------------|---------------|----------------|---------------|-----------|
| 1       | me@domain.com | encrypted     | Foo            | Bar           | farmer    |
'---------'---------------'---------------'----------------'---------------'-----------'

This is my routes file:

<?php
Route::get('/login', 'UsersController@login');

Auth::routes();
Route::get('/dashboard', 'HomeController@dashboard')->name('dashboard');
Route::get('/users/grid', 'UsersController@grid');
Route::resource('/users', 'UsersController');

LoginController.php

<?php
namespace App\Http\Controllers\Auth;

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

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;

    /**
     * @var string
     */
    protected $redirectTo = '/dashboard';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * @return string
     */
    public function username()
    {
        return 'user_username';
    }

    /**
     * @param Request $request
     * @param $user
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function authenticated(Request $request, $user)
    {
        return $user->user_type === 'farmer' ? redirect('/dashboard') : redirect('/admin');
    }
}

User.php

<?php
namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * @var array
     */
    protected $fillable = [
        'user_username', 'user_firstname', 'user_lastname', 'user_password',
    ];

    /**
     * @var array
     */
    protected $hidden = [
        'user_password', 'remember_token',
    ];

    /**
     * @var bool
     */
    public $timestamps = false;

    /**
     * @return mixed|string
     */
    public function getAuthPassword()
    {
        return $this->user_password;
    }

    /**
     * @return string
     */
    public function getKey()
    {
        return $this->user_id;
    }
}

WHAT I'VE DONE

I've read various questions on stackoverflow but for some reason I can't get login to work.

I created the auth using php artisan make:auth. I've tried reading the documentation too, but still no luck.

QUESTION

How do I get it to redirect to the dashboard after login? What am I missing?

Bird87 ZA
  • 2,259
  • 8
  • 34
  • 64
  • you have to change `user_password` field to `password`. Because some of the methods in laravel using hard coded `password` field as password. You firstly change that then It will work. – Lakhwinder Singh Oct 14 '18 at 06:04
  • I would prefer to not change the password field in the db. Is there some way that I can perhaps alter it before it goes through all the laravel code? – Bird87 ZA Oct 14 '18 at 06:05
  • you have to override those functions in LoginController with change `password` field to `user_password` field – Lakhwinder Singh Oct 14 '18 at 06:07
  • Which functions are these? If you could maybe point me in the right direction. Also, it doesn't make sense, because if I put a `dd($user)` in the `authenticated` call in my `LoginController`, it does show the authenticated user. – Bird87 ZA Oct 14 '18 at 06:17

4 Answers4

2

You need to add this prop in your user model.

protected $primaryKey = 'user_id';

Remove the authenticated() method from login controller.

And handle the redirection based on user type inside RedirectIfAuthenticated middleware

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {
        if (Auth::guard($guard)->check()) {
          if (Auth::guard($guard)->user->user_type === 'farmer'){
            redirect('/dashboard'); // make sure the urls is correct with condition above 
          }
          return redirect('/admin');
        }

        return $next($request);
    }
}

Extra step inside App\Exceptions\Handler class

Add this method if you have different login pages for each user type

/**
 * @param Request $request
 * @param AuthenticationException $exception
 * @return JsonResponse|RedirectResponse|\Symfony\Component\HttpFoundation\Response
 */
protected function unauthenticated($request, AuthenticationException $exception)
{
    if ($request->expectsJson()) {
        return response()->json(['error' => 'Unauthenticated.'], 401);
    }
    if ($request->is('dashboard') || $request->is('dashboard/*')) {
        return redirect()->guest('/dashboard/login');
    }

    return redirect()->guest('farmer/login');
}
Ahmad Elkenany
  • 565
  • 5
  • 22
1

I have had the same problem yesterday night. I have found that the issue is Auth::attempt() does not persist the login so when a user is logged in successfully, it was dropped in the session after redirect to /home.

Below link provided the answer to solve it: Laravel Auth:attempt() will not persist login

Try to add something like

protected $primaryKey = 'user_id'; in class User{}

(app/models/User.php)

(Field user_id is auto increment key in my Schema for 'users' table)

Wang Peter
  • 11
  • 1
-1

You are using user_password field instead of password field. So you need to do some changes in LoginController.php file. Below is the updated LoginController. Try to do changes like this and then try to login

<?php
namespace App\Http\Controllers\Auth;

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

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;

    /**
     * @var string
     */
    protected $redirectTo = '/dashboard';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

    /**
     * @return string
     */
    public function username()
    {
        return 'user_username';
    }

    /**
     * @param Request $request
     * @param $user
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
     */
    public function authenticated(Request $request, $user)
    {
        return $user->user_type === 'farmer' ? redirect('/dashboard') : redirect('/admin');
    }

    /**
     * Validate the user login request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            $this->username() => 'required|string',
            'user_password' => 'required|string',
        ]);
    }

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    protected function credentials(Request $request)
    {
        return $request->only($this->username(), 'user_password');
    }
}

I added two functions validateLogin and credentials where default field was password. and I changed this with user_password.

Lakhwinder Singh
  • 5,430
  • 5
  • 25
  • 50
  • This doesn't work. My login view file, has `password` as the input field. My `User.php` has an accessor for password that authenticates against my db field, `user_password`. Like I said in my comment, if I `dd($user)` in my `authenticated` function, it returns the authenticated user, it just doesn't redirect. – Bird87 ZA Oct 14 '18 at 07:31
-1

for authentication in laravel first use php artisan make:auth command

and in your web.php add Auth::routes(); only which have all authentication routes

and to check if you are login or not you should add $this->middleware('auth'); in constructor of controller like

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

and do not forget to call auth class like use Auth;

or you can check authentication in your routes by add middleware auth

and also check https://laravel.com/docs/5.7/authentication documentaion

Sally Akl
  • 94
  • 1
  • 6