I'm working on a Laravel 8 project that logs a user in through one of two Active Directory servers using LDAP Record 2.5 with a Users table in my DB (MySQL 8) just to have access to some basic info like name, email and a unique user id.
I got the initial part working - I get a successful login to the AD and my users table gets automatically synced with the Active Directory data. If I do a dd() right after the auth()->attempt() I will get what looks like a normally initialized User model and the relevant row in the users table has its remember_token field filled in.
But regardless of whether I pass a remember parameter or not there is no actual authentication - calling auth()->user() or Auth::user() returns a null anywhere except for the login method itself and the debug toolbar doesn't show a user model.
This is the code of my custom LoginController:
public function store(Request $request) {
$credentials = [
'mail' => $request->input('username').'#pio.rs',
'password' => $request->input('password'),
];
$remember = ($request->input('remember') == true) ? true : false;
auth()->shouldUse('pio');
if (auth()->attempt($credentials, $remember)) {
dd(auth()->user()); //returns working user model here
return redirect()->route('home');
} else {
auth()->shouldUse('voj');
if (auth()->attempt($credentials, $remember)) {
return redirect()->route('home');
}
}
}
And these are the settings in my config/auth.php file:
'defaults' => [
'guard' => 'pio',
'passwords' => 'users',
],
'guards' => [
'voj' => [
'driver' => 'session',
'provider' => 'voj',
],
'pio' => [
'driver' => 'session',
'provider' => 'pio',
],
],
'providers' => [
'voj' => [
'driver' => 'ldap',
'model' => App\Ldap\Voj\User::class,
'database' => [
'model' => App\Models\User::class,
'password_column' => false,
'sync_attributes' => [
'email' => 'mail',
'name' => 'cn',
],
'sync_existing' => [
'email' => 'mail',
//'operator' => 'ilike',
],
]
],
'pio' => [
'driver' => 'ldap',
'model' => App\Ldap\Pio\User::class,
'database' => [
'model' => App\Models\User::class,
'password_column' => false,
'sync_attributes' => [
'email' => 'mail',
'name' => 'cn',
],
'sync_existing' => [
'email' => 'mail',
//'operator' => 'ilike',
],
]
],
Any idea what I'm doing wrong?
Found the solution - just needed to call the auth middleware with middleware(['auth:pio,voj']) instead of just middleware(['auth'])
Related
I have already multi auth system in my project, one for the user and the other for admin, and here are my guards
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => admin_auth',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admin_auth' => [
'driver' => 'eloquent',
'model' => App\Models\admins\admin::class,
],
],
and I would like to have multi auth for API using sanctum because I only do it for one auth which is the user
here is my code to create a token
// Validate the form data
$this->validate($request, [
'phone_number' => 'required|numeric',
'password' => 'required',
//'device_name' => 'required', for mobile app //need to be placed in token name
]);
$user = User::where('phone_number', $request->input('phone_number'))->first();
// Check password
if(!$user || !Hash::check($request->input('password'), $user->password)) {
return response([
'message' => 'The phone number or passowrd is not correct'
], 401);
}
$roles = $user->getRoleNames()->toArray();
$token = $user->createToken('mymobile_token', $roles)->plainTextToken;
so how to create another auth for the admin?
I changed the default guard to something like below
auth.php
'defaults' => [
'guard' => 'employee',
'passwords' => 'users',
],
'guards' => [
'employee' => [
'driver' => 'session',
'provider' => 'employees',
],
],
'providers' => [
'employees' => [
'driver' => 'eloquent',
'model' => App\Employee::class,
],
],
However, I can't get the current login user from this Auth facade Auth::guard('employee')->user()
this returns an empty result.
But the user login work successfully Auth::attempt(['email' => $request->email, 'password' => $request->password, 'status' => 1])
I really appreciate your help.
Thanks
Thanks for the viewers. Instead of using Auth::guard('employee')->user() facade, I tried login method $request call. It works for me. $request->user();
public function login(Request $request){
$request->user();
}
First time i've asked anything on here before and not the most experienced so please be nice!
I have two tables set up in my DB - Users & Agents.
I have tried multiple ways in which to login both of the users and would ideally like them to be able to login from the same form and do a check on both guards to see if the credentials are valid but for some reason when doing doing attempts on the guards it will only work for the table my default is set to in my auth.php file.
Guards I am attempting:
Auth::guard('web')->attempt($credentials)
Auth::guard('agent')->attempt($credentials)
If I set my default guard in my auth.php file to the web guard its works fine and logs in the matching credentials from the Users table but when trying the agents credentials it shows in my network tab:
Login -
POST 302 found
Agent -
GET 302 found
Login -
Get 200 OK
So it's almost like it acknowledges to credentials are correct and re-directs but then doesnt carry on using the selected guard?
LoginController - DoLogin
Auth.php configeration
in your config/auth.php copy below code :
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'agent' => [
'driver' => 'session',
'provider' => 'agents',
]
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'agents' => [
'driver' => 'eloquent',
'model' => App\Agent::class,
]
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
'agents' => [
'provider' => 'agents',
'table' => 'password_resets',
'expire' => 60,
],
],
];
in your Login Controller :
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:6'
]);
if (Auth::guard('agent')->attempt(['email' => $request->email, 'password' => $request->password])) {
return redirect('/dashboard/agent');
}
if(Auth::guard('web')->attempt(['email' => $request->email, 'password' => $request->password])){
return redirect('/dashboard/user');
}
return redirect()->back()->withInput($request->input());
}
I am trying to make a user authentication with two tables, a different table to 'users' and the one of 'users' which is the one with default Laravel, use Laravel passport. The detail is when I try to login with the second table I can not do the authentication because I do not recognize the users of the second table.
-Model User2: ->protected $guard_name='api2';
-connection: ->protected $connection='mysql2';
**config/auth.php**
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
'api2' => [
'driver' => 'passport',
'provider' => 'users2',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'user2' => [
'driver' => 'eloquent',
'model' => App\User2::class,
],
],
My controller
public function login(Request $request)
{
if (Auth::attempt($request->only('email', 'password'))) {
$email = $request->only('email');
$token = $user->createToken('123456')->accessToken;
$user->withAccessToken($token);
$email=json_decode(json_encode($email));
$user = User2::where('email', $email->email )->first()->only('id','name','email','employee_id');
$user1 = User::find($user['id']);
if(!$user1->hasAnyRole(Role::all())){
return response()->json([
'success' => false,
'data' => '',
'msg' => "does not have assigned role"
], 403);
}
$roles = $user1->getRoleNames()->first();
$role = Role::findByName($roles,'api');
$user=json_decode(json_encode($user));
return response()->json([
'success' => true,
'token' => $token,
'data' => [
'user_id' => $user->id,
'name' => $user->name,
'email' => $user->email,
'employee_id' => $user->employee_id,
'role_id' => $role->id,
'role_name' => $role->name
],
'msg' => "Successfully"
], 200);
} else {
return response()->json(['error' => 'Unauthorised'], 401);
}
}
While Laravel Passport is useful to most developers, it is still a puzzle on how to authenticate multiple (user) models within it since underneath(by default), it looks on the users table only.
https://github.com/jsdecena/laravel-passport-mutiauth
How can I use more the one table to attempt login ?
I tried following setting, but it will change to use Admin::class, and the User::class attempt will fail immediately.
app/config
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => FACI\Entities\User::class,
'model' => FACI\Entities\Admin::class,
],
]
this is my attempt
$attempt = \Auth::attempt([
'name' => $this->request->name,
'password' => $this->request->password,
]);
How to told the code to binding the table?