I am working on custom auth for Laravel 11 using only laravel/ui as I do not need any of the features in Breeze/Jetstream.
In my users table (custom, external service table), a users’ “email address” is compromised of two fields, their userid
and their realm
.
On my Users model I have:
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'passwd',
];
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'passwd' => 'hashed',
'isActive' => 'boolean',
'isPriv' => 'boolean',
];
}
/**
* Get the user's email address.
*/
protected function authEmail(): Attribute
{
return Attribute::make(
get: fn () => $this->userid . '@' . $this->realm,
);
}
/**
* Get the user's active status.
*/
protected function isActive(): Attribute
{
return Attribute::make(
get: fn () => $this->active,
);
}
/**
* Get the user's priv status.
*/
protected function isPriv(): Attribute
{
return Attribute::make(
get: fn () => $this->priv > 0,
);
}
/**
* Get the password field for the user.
*
* @return string
*/
public function getAuthPassword()
{
return $this->passwd;
}
… authEmail
is fillable.
In my LoginController:
<?php
namespace AppHttpControllersAuth;
use AppHttpControllersController;
use IlluminateFoundationAuthAuthenticatesUsers;
use IlluminateHttpRequest;
use IlluminateHttpRedirectResponse;
use IlluminateSupportFacadesAuth;
class LoginController extends Controller
{
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');
//$this->middleware('auth')->only('logout');
}
/**
* Column name for auth.
*/
public function username()
{
return 'authEmail';
}
/**
* Handle an authentication attempt.
*/
public function authenticate(Request $request): RedirectResponse
{
$credentials = $request->validate([
'authEmail' => ['required', 'email'],
'passwd' => ['required'],
]);
if (Auth::attempt([$credentials, 'isActive' => 1, 'isPriv' => 1])) {
$request->session()->regenerate();
return redirect()->intended('home');
} else {
dd('attempt failed');
}
return back()->withErrors([
'authEmail' => 'The provided credentials do not match our records.',
])->onlyInput('authEmail');
}
}
…the email
field in the login form has been updated to authEmail
.
However, despite the accessor and setting username()
to authEmail
, when I attempt to auth, I get:
column "authEmail" does not exist
How can I customize the email part of the authentication workflow to use my aggregate attribute instead of a single column?
Thank you.