i am trying to create a multiple authentication in Laravel 7 with custom guards and when i try to login am getting this error "SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'where clause' (SQL: select * from admins where email = mukamba#gmail.com and 0 is null limit 1)"
My auth.php in config
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
My adminLoginController
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use auth;
class AdminLoginController extends
Controlle
r
{
public function __construct()
{
$this->middleware('guest:admin');
}
public function showLoginForm()
{
return view('auth.admin-login');
}
public function login(Request $request)
{
// validate the data
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
// attempt user to login
if(auth::guard('admin')->attempt(['email' => $request->email, 'password'=> $request->password, $request->remember])){
//if susscefull redirect to the intended location
return redirect()->intended(route('admin.dashboard'));
}
// if unsuccesfull return to the page they were
}
}
My Admin model
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use Notifiable;
protected $guard = 'admin';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'job_title',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
LoginController
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
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 = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
}
The problem is somewhere in your password when you are passing it.
select * from admins where email = mukamba#gmail.com and 0 is null limit 1) I gues that you are getting this error when trying to log in. Check out Login controller and see the parameters that you are passing. Or drop the controller here so we can provide more info.
The attempt function was supposed to be like this
if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->get('remember'))) { return redirect()->intended(route('admin.dashboard'));
}
Related
I'm using Laravel passport for API authentication, with api provider 'user' and web provider 'admin'. However, my API login URL keeps using the default provider for web instead of its own provider.
config/auth.php:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'admin',
],
'api' => [
'driver' => 'passport',
'provider' => 'user',
'hash' => 'false',
],
],
'providers' => [
'admin' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
'user' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
],
User Model:
<?php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use \App\Http\Traits\UsesUuid, HasApiTokens,Notifiable;
protected $table = 'user';
protected $primaryKey = 'user_id';
protected $fillable =
['user_id',
'user_fname',
'user_lname',
'user_email',
'password',
'user_contact',
'user_token' ];
protected $hidden = [
'password', 'remember_token',
];
protected $casts = [
'email_verified_at' => 'datetime',
];
public function setPasswordAttribute($password)
{
$this->attributes['password'] = bcrypt($password);
}
}
Admin Model:
<?php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use Notifiable;
protected $table = 'admin';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime'
];
}
API Auth Controller:
public function login(Request $request){
$credentials = request(['user_email', 'password']);
if(!auth()->attempt($credentials)){
return response()->json([
"message"=>"Invalid credentials"
], 201);
}
$accessToken = auth()->user()->createToken('authToken')->accessToken;
return response()->json([
"message"=>"Login successful",
"user"=>auth()->user(),
"access_token"=>$accessToken
], 201);
}
Login route:
Route::post('/login', 'AuthController#login');
My error is the login route uses the default Admin model instead of the User model specified for the API provider giving me this error:
Illuminate\Database\QueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_email' in 'where clause' (SQL: select * from `admin` where `user_email` = user#gmail.com limit 1)
I have seen a similar error here https://laracasts.com/discuss/channels/laravel/changing-the-model-provider-laravel-passport-authenticates-against and tried the fixes suggested here https://github.com/laravel/passport/issues/161#issuecomment-299690583 but they do not work
you need to create a user guard as you need users table session driver to call attempt() function
config/auth.php:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'admin',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'user',
'hash' => 'false',
],
],
then your code should be like this
public function login(Request $request)
{
$credentials = request(['user_email', 'password']);
if (!auth()->guard('user')->attempt($credentials)) {
return response()->json([
"message" => "Invalid credentials"
], 201);
}
$accessToken = auth()->guard('user')->user()->createToken('authToken')->accessToken;
return response()->json([
"message" => "Login successful",
"user" => auth()->user(),
"access_token" => $accessToken
], 201);
}
NOTE:- we create new guard because passport driver not allow to use attempt() and web guard you have set admin table so
I am new to laravel 5.8 , am not able to use Auth in api controllers, below are the details :
I have changed default users table from users to User
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = 'User';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'firstName', 'lastName', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Did not change anything in auth.php
<?php
return
['defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
My question : How can I make Auth::check() work in this controller and get user id. This returns Not logged
<?php
namespace App\Http\Controllers\api;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Session;
use DB;
use Response;
use Auth;
class AccountsController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
//
$userID = Auth::id();
if (Auth::check()) {
return "User logged , user_id : ".$userID ;
}else{
return "Not logged"; //It is returning this
}
}
}
I have tried several answers of similar questions ( Q1 Q2 ) but it didn't work.
There would be no logged in user if using the API routes. Authentication for API's are done by tokens, you can read about it in the Laravel docs.
The session middleware is not called unless you use the web routes so the session is not started and therefore its not possible to use Auth.
What is it your trying to achieve as its not normal to use Auth with API routes.
Use can try this for setting auth user in the session. This will set the user after authentication and set Auth::user().
Auth::attempt(['email' => request('email'), 'password' => request('password')])
From your controller, it looks like you are trying to access session while using an API route. API routes don't have access to session. You should call your controller from a route defined in web.php or you should authenticate using tokens. Consult Laravel docs to explore API authentication possibilities.
I'm trying to configure the laravel's auth to fit with my db.
But whatever I do, override properties like protected $table='my_table'; or public function username() { return 'email_user'} in LoginController, it ignore everything.
Does anyone know how to parameter the auth of laravel with different database ?
Here is what I changed in LoginController:
public function username()
{
return 'email_user';
}
And in the User model :
protected $table = "pays";
protected $primaryKey = "id_user";
public function getAuthPassword() {
return $this->password_user;
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name_user', 'surname_user', 'email_user', 'password_user', 'sex_user', 'birth_user', 'address_user',
'city_user', 'pc_user', 'phone_user', 'pic_user', 'status_user', 'license_user', 'urssaf_user',
'remember_token', 'created_at', 'updated_at',
];
EDIT : config/auth.php :
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
LoginController :
<?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 = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function username()
{
return 'email_user';
}
}
In your login form keep password field with name=password:
<input type="text" name="email_user">
<input type="password" name="password">
I'm trying to create multi login in laravel 5.6 and this error appeared, can anyone help me?
Symfony \ Component \ Debug \ Exception \ FatalThrowableError (E_RECOVERABLE_ERROR)
Type error: Argument 2 passed to Illuminate\Auth\SessionGuard::__construct() must be an instance of Illuminate\Contracts\Auth\UserProvider, null given, called in C:\wamp64\www\Laravel\Sistema\oficial\vendor\laravel\framework\src\Illuminate\Auth\AuthManager.php on line 123
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Route;
use Illuminate\Support\Facades\Auth;
class EmployeeLoginController extends Controller
{
public function __construct()
{
$this->middleware('auth:employee');
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (Auth::guard('employee')->attempt($credentials)) {
return redirect()->intended(route('admin.dashboard'));
}
return redirect()->back()->withInput($request->only('email', 'remember'));
}
}
guard:
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'employee' => [
'driver' => 'session',
'provider' => 'employees',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'employee' => [
'driver' => 'eloquent',
'model' => App\Employee::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
ReditectIfAuthenticated
<?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)
{
switch ($guard) {
case 'employee':
if (Auth::guard($guard)->check()) {
return redirect('/dashboardemployee');
}
break;
default:
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
break;
}
return $next($request);
}
}
model:
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Employee extends Authenticatable
{
protected $guard = 'employee';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
'email',
'password',
'photo',
'status',
'connect_email',
'connect_senha',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
The provider is named wrong:
'employee' => [
'driver' => 'eloquent',
'model' => App\Employee::class,
],
should be
'employees' => [
'driver' => 'eloquent',
'model' => App\Employee::class,
],
I am learning laravel and i decided to make a custom authentication in laravel . I could register my users but when i try to login i get this error ?
Type error: Argument 2 passed to Illuminate\Auth\SessionGuard::__construct() must implement interface Illuminate\Contracts\Auth\UserProvider, null given,
These are my resources
My AdminUser Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Notifications\Notifiable;
use Illuminate\Auth\Authenticatable as AuthenticableTrait;
use Illuminate\Foundation\Auth\Access\Authorizable;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
class AdminUser extends Eloquent implements AuthenticatableContract,AuthorizableContract
{
public $table = "admin_users";
use Notifiable;
use AuthenticableTrait;
use Authorizable;
protected $fillable = [
'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
My AdminUserController
<?php
namespace App\Http\Controllers;
use App\AdminUser;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\Http\Requests\LoginRequest;
use App\Http\Requests\RegisterRequest;
use Auth;
use Response;
class AdminUserController extends Controller {
use AuthenticatesUsers;
/**
* the model instance
* #var AdminUser
*/
protected $user;
/**
* The Guard implementation.
*
* #var Authenticator
*/
protected $admin;
/**
* Create a new authentication controller instance.
*
* #param Authenticator $admin
* #return void
*/
public function __construct(Guard $admin, AdminUser $user)
{
$user = AdminUser::first();
Auth::login($user);
$this->middleware('admin', ['except' => ['getLogout']]);
}
/**
* Show the application registration form.
*
* #return Response
*/
public function getRegister()
{
return view('admin/admin_users/register');
}
/**
* Handle a registration request for the application.
*
* #param RegisterRequest $request
* #return Response
*/
public function postRegister(RegisterRequest $request)
{
AdminUser::create([
'email' => $request->email,
'password' => bcrypt($request->password),
]);
return redirect('backend-admin/dashboard');
}
/**
* Show the application login form.
*
* #return Response
*/
public function getLogin()
{
return view('admin/admin_users/login');
}
/**
* Handle a login request to the application.
*
* #param LoginRequest $request
* #return Response
*/
public function postLogin(LoginRequest $request)
{
if (Auth::guard('admin')->attempt($request->only('email', 'password')))
{
return redirect()->intended('/backend-admin/dashboard');
}
return redirect('/backend-admin')->withErrors([
'email' => 'The credentials you entered did not match our records. Try again?',
]);
}
/**
* Log the user out of the application.
*
* #return Response
*/
public function getLogout()
{
Auth::guard('admin')->logout();
return redirect('/backend-admin');
}
protected function guard()
{
return Auth::guard();
}
}
My VerifyAdmin Middleware
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\Facades\Auth;
class VerifyAdmin
{
/**
* The Guard implementation.
*
* #var Guard
*/
protected $admin;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
// dd($auth);
$this->admin = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ($this->admin->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('backend-admin');
}
}
return $next($request);
}
}
I also defined guards in auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admin' => [
'driver' => 'eloquent',
'model' => App\AdminUser::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
Also defined middleware in kernel.php
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'admin' => \App\Http\Middleware\VerifyAdmin::class,
Feel free to correct me if i am wrong anywhere or if i have missed anything .
I found what was bugging my program , i did defined guard function in my controller but forget to add the guard in function , i fixed it by defining guard.
I think the problem are those 2 lines:
$user = AdminUser::first();
Auth::login($user);
What's the point of running it? First of all, I see you have here login action and it seems you automatically login admin when on login page - it doesn't make much sense.
Also those 2 lines won't do anything that should be done I think - because when admin logs in, well you log him in so there's no point to login him in each request assuming you are using sessions.
You need to change the admin provider name from admin to admins.
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [ // ***this is the change that should be made***
'driver' => 'eloquent',
'model' => App\AdminUser::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];