Show us what you have done so far. Have you added the provider to config files, if you have cached your config ever, clear the cache and try ....
Replacing the laravel authentication with a custom authentication errors
had a look @https://laracasts.com/index.php/discuss/channels/laravel/replacing-the-laravel-authentication-with-a-custom-authentication but I seem to be having a problem errors any help or to use a different approach please
InvalidArgumentException in CreatesUserProviders.php line 40:
Authentication user provider [custom] is not defined.
thanks for the response here is what I have done
config/app
App\Providers\CustomAuthProvider::class,
and in my config/auth
'providers' => [
'users' => [
//'driver' => 'eloquent',
'driver' => 'custom',
'model' => App\User::class,
],
in my app/customUserProvider
<?php
namespace App;
use App\User;
use Carbon\Carbon;
use Illuminate\Auth\GenericUser;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
class CustomUserProvider implements UserProvider {
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
// TODO: Implement retrieveById() method.
$qry = User::where('admin_id','=',$identifier);
if($qry->count() >0)
{
$user = $qry->select('admin_id', 'username', 'first_name', 'last_name', 'email', 'password')->first();
$attributes = array(
'id' => $user->admin_id,
'username' => $user->username,
'password' => $user->password,
'name' => $user->first_name . ' ' . $user->last_name,
);
return $user;
}
return null;
}
/**
* Retrieve a user by by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
// TODO: Implement retrieveByToken() method.
$qry = User::where('EmailAddress','=',$identifier)->where('remember_token','=',$token);
if($qry->count() >0)
{
$user = $qry->select('Username','EmailAddress', 'Password')->first();
$attributes = array(
'Username' => $user->username,
'Password' => $user->password,
);
return $user;
}
return null;
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
// TODO: Implement updateRememberToken() method.
$user->setRememberToken($token);
$user->save();
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// TODO: Implement retrieveByCredentials() method.
$qry = User::where('Username','=',$credentials['Username']);
if($qry->count() >0)
{
$user = $qry->select('Username','EmailAddress','Password')->first();
return $user;
}
return null;
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
// TODO: Implement validateCredentials() method.
// we'll assume if a user was retrieved, it's good
if($user->Username == $credentials['Username'] && $user->getAuthPassword() == md5($credentials['Password'].\Config::get('constants.SALT')))
{
$user->last_login_time = Carbon::now();
$user->save();
return true;
}
return false;
}
}
in app/providers/customAuthProvider
<?php
namespace App\Providers;
use App\CustomUserProvider;
use Illuminate\Support\ServiceProvider;
class CustomAuthProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
$this->app['auth']->extend('custom',function()
{
return new CustomUserProvider();
});
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//
}
}
please note I am using laravel 5.2
Where's customAuthProvider? OK, saw the edit ...
extend() is for guards/driver, look here for adding providers https://laravel.com/docs/5.2/authentication#adding-custom-user-providers
Looked at the documentation I can not spot anything wrong please advice
I can, but it would be nice if you spot it yourself. I can give you a hint tough, there's a difference between a guard driver and user provider. First, make sure what is that you are trying to implement, a guard or a provider. Once you figure this out, things will fall in place.
like I explained I am trying to get that to work as the code reads you should be pointing me towards the right direction not insulting my intelligence I want to get that to work accordingly I will appreciate if you can criticize and help rather than mary go round cause thats not helping if I knew how I will not post, so if you see something wrong advice accordingly
you should be pointing me towards the right direction
Thats exactly what i did. Just didn't gave you the answer.
Thanks, but I will pass. I gave you all the hints and the answer is right there, and yes, the meryy go round is for you. And as far as i can tell, this forum is more for learning than fixing the code, unfortunately people have resorted to later lately :(
thanks for trying I finally found the problem with this .The problem in Laravel 5 lies with the in app/providers/customAuthProvider the code should look like this
$this->app['auth']->provider('custom',function()
not like this as we had it before
$this->app['auth']->extend('custom',function()
and for reference purpose I found that here @http://laravel.io/forum/11-04-2014-laravel-5-how-do-i-create-a-custom-auth-in-laravel-5
extend() is for guards/driver, look here for adding providers https://laravel.com/docs/5.2/authentication#adding-custom-user-providers
And thats what i exactly said, if only you had cared to look :(
thanks man you made me look I had been on it for LONG times so was getting frustrated but now I have this the variable defined in my user model are not the ones being used when I try to log in to the app why is this and how can it be solved nothing changed still the same as above but for some reason the query sent to the database does not look into my model so it still passes attributes from laravel rather than custom ones which I want
some reason the query sent to the database does not look into my model so it still passes attributes from laravel rather than custom ones which I want
What model? What query, what is the outcome and what are you expecting ?
I am trying to log in but I get this error
ErrorException in CustomUserProvider.php line 96:
Undefined index: Username
in CustomUserProvider.php line 96
at HandleExceptions->handleError('8', 'Undefined index: Username', 'CustomUserProvider.php', '96', array('credentials' => array('email' => 'email', 'password' => 'pass'))) in CustomUserProvider.php line 96
at CustomUserProvider->retrieveByCredentials(array('email' => 'email', 'password' => 'pass')) in SessionGuard.php line 353
at SessionGuard->attempt(array('email' => 'email', 'password' => 'pass'), false) in AuthenticatesUsers.php line 74
at AuthController->login(object(Request))
at call_user_func_array(array(object(AuthController), 'login'), array(object(Request))) in Controller.php line 80
at Controller->callAction('login', array(object(Request))) in ControllerDispatcher.php line 146
at ControllerDispatcher->call(object(AuthController), object(Route), 'login') in ControllerDispatcher.php line 94
and here is the model
class User extends Model
{
protected $table = 'users';
public $timestamps = false;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'Username',
'EmailAddress',
'Password'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'Password', 'remember_token',
];
public function getAuthPassword() {
return $this->Password;
}
public function getAuthUsername() {
return $this->Username;
}
}
SessionGuard->attempt(array('email' => 'email', 'password' => 'pass'), false)
You are not even passing the credentials to attempt function.
I am not trying to be a dick here, but as long as you are doing for learning purposes it OK, but for production code, this looks like a very bad spaghetti, all mixed up. So, unless you are sure of what you are doing, you should not touch auth and security codes. Best practices have already been implemented.
Now if you could tell me, (not that you are implementing a custom user provider) but why and what you want, i might be able to provide a better solution. There's no need to implement the custom provider unless absolutely necessary, there are ways around.
thanks man but this is what I am trying to do every thing else is fine just to get the auth working my problem is I have a database with the user table already defined and populated I need to be able to use this application with the same table that's why I needed to do the custom auth since I could not change or override the call to my db with laravel attributes
Can't you just over-ride the login() method in the existing auth controller to do your custom stuff?
Naah, just that might not work, you can assign any user for that particular request, but for sessions to work, the provider might have to be configured,
It's worked every time I've done it :-) Maybe I've just been lucky ;-)
can you share your override maybe I try that please @ohffs
@ohffs May be I am missing something, will be glad if you could explain.
@d3xt3r I quite often have users auth'd via LDAP, or locally with some additional rules. So something like :
AuthController.php
...
public function login(Request $request)
{
$this->validate($request, [
'username' => 'required', 'password' => 'required',
]);
$username = trim(strtolower($request->input('username')));
$password = $request->input('password');
// if the username is an email address, try and find them in the local db
if (preg_match('/\@/', $username)) {
// try normal local laravel Auth::attempt() login and redirect out
}
// try LDAP auth
$result = $this->ldap->authenticate($username, $password);
if (!$result) {
return redirect()->refresh()->withErrors(['errors' => 'Username and/or password are incorrect.']);
}
$username = $result['username'];
$user = User::where('username', '=', $username)->first();
if (!$user) {
// create a new $user from the ldap $results or bail out depending on the app
}
Auth::login($user);
return redirect()->intended($this->redirectTo);
}
}
@tim3011 see above
@ohffs I see, but I was trying to exactly avoid these, creating duplicate user tables :)
Reason, once i have it saved to second database, i will have to synchronise it at a regular interval., plus he already have a database that can be accessed directly.
@tim3011 So just clear up your code a bit, be consistent with the fields. Update your auth form to change the fields accordingly. What you have already done should work. I have just put some comments if you need to look at it
class CustomUserProvider implements UserProvider
{
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveById($identifier)
{
return User::where('admin_id','=',$identifier)
->select('admin_id', 'username', 'first_name', 'last_name', 'email', 'password')->first();
}
/**
* Retrieve a user by their unique identifier and "remember me" token.
*
* @param mixed $identifier
* @param string $token
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByToken($identifier, $token)
{
// do you really have a remember token in old db
// if not no need to implement this
// or set up a different table for remember tokens
}
/**
* Update the "remember me" token for the given user in storage.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param string $token
* @return void
*/
public function updateRememberToken(Authenticatable $user, $token)
{
// Like above case
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
// keep your fields consistent. Some where you are using username
// and some where Username
return User::where('username','=',$credentials['username'])->first();
// and where from these fields are coming previously you
// $user = $qry->select('Username','EmailAddress', 'Password')->first();
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, array $credentials)
{
// whatever your password logic is here
}
}
thanks that will be helpful if you show what you have done I had already done something on the authenticatesUsers and I think I went to far, now it only loads no errors but it does not take me inside the application .anything that will help appreciated and if you know of an video article i can follow as well thanks need to get this working had been on it for two days running thanks everyone who helps
<?php
namespace Illuminate\Foundation\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Lang;
trait AuthenticatesUsers
{
use RedirectsUsers;
/**
* Show the application login form.
*
* @return \Illuminate\Http\Response
*/
public function getLogin()
{
return $this->showLoginForm();
}
/**
* Show the application login form.
*
* @return \Illuminate\Http\Response
*/
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('auth.login');
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function postLogin(Request $request)
{
return $this->login($request);
}
/**
* Handle a login request to the application.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request);
}
/**
* Validate the user login request.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->loginUsername() => 'required', 'Password' => 'required',
]);
}
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
* @param bool $throttles
* @return \Illuminate\Http\Response
*/
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
return redirect()->intended($this->redirectPath());
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
protected function sendFailedLoginResponse(Request $request)
{
return redirect()->back()
->withInput($request->only($this->loginUsername(), 'remember'))
->withErrors([
$this->loginUsername() => $this->getFailedLoginMessage(),
]);
}
/**
* Get the failed login message.
*
* @return string
*/
protected function getFailedLoginMessage()
{
return Lang::has('auth.failed')
? Lang::get('auth.failed')
: 'These credentials do not match our records.';
}
/**
* Get the needed authorization credentials from the request.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function getCredentials(Request $request)
{
return $request->only($this->loginUsername(), 'Password');
}
/**
* Log the user out of the application.
*
* @return \Illuminate\Http\Response
*/
public function getLogout()
{
return $this->logout();
}
/**
* Log the user out of the application.
*
* @return \Illuminate\Http\Response
*/
public function logout()
{
Auth::guard($this->getGuard())->logout();
return redirect(property_exists($this, 'redirectAfterLogout') ? $this->redirectAfterLogout : '/');
}
/**
* Get the guest middleware for the application.
*/
public function guestMiddleware()
{
$guard = $this->getGuard();
return $guard ? 'guest:'.$guard : 'guest';
}
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function loginUsername()
{
return property_exists($this, 'Username') ? $this->Username : 'EmailAddress';
}
/**
* Determine if the class is using the ThrottlesLogins trait.
*
* @return bool
*/
protected function isUsingThrottlesLoginsTrait()
{
return in_array(
ThrottlesLogins::class, class_uses_recursive(static::class)
);
}
/**
* Get the guard to be used during authentication.
*
* @return string|null
*/
protected function getGuard()
{
return property_exists($this, 'guard') ? $this->guard : null;
}
}
I only changed the attributes to match what I have please help
@d3xt3r I admit I rather skimmed reading most of the first page as it was a bit painful ;-)
@tim3011 Again, bad spaghetti :( , show me the following and i will give you the solution. The inconsistency is all over the place, somewhere its username, somewhere username, and all of a sudden EmailAddress comes into play.
- What the fields in your old user table, table name, and what are the login fields. And please be consistent with the caps.
@tim3011 thanks, save my time got to your solution after 3 days. now i can connect opencart store to my laravel project.
Please or to participate in this conversation.