I,ve just started with Laravel but i still have an problem with my authentication. I need to build my system on an existing database structure. The user table password uses md5 and i like to convert that to the Laravel Hash. But after converting the md5 password to hash the login fails with this new hash. I cannot find the solution for this problem.
Table
id (int11)
gebruikersnaam (varchar 255)
wachtwoord (varchar 255)
updated_at (timestamp)
created_at (timestamp)
remember_token (timestamp)
User model
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'gebruikers';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('wachtwoord');
}
Login controller
class LoginController extends BaseController {
function starten(){
$rules = array(
'gebruikersnaam' => 'required', // make sure the email is an actual email
'wachtwoord' => 'required' // password can only be alphanumeric and has to be greater than 3 characters
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('/')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
$user = User::where('gebruikersnaam','=',Input::get('gebruikersnaam'))
->first();
if(isset($user)) {
if($user->wachtwoord == md5(Input::get('wachtwoord'))) {
$user->wachtwoord = Hash::make(Input::get('wachtwoord'));
$user->save();
}
}
$userdata = array(
'gebruikersnaam' => Input::get('gebruikersnaam'),
'wachtwoord' => Input::get('wachtwoord')
);
if (Auth::attempt($userdata)) {
return Redirect::to('users/dashboard')
->with('message', 'You are now logged in!');
} else {
return Redirect::to('/')
->with('message', 'Deze combinatie van gebruikersnaam en wachtwoord lijkt helaas niet te kloppen')
->withInput();
}
}
}
}
Auth
return array(
'driver' => 'eloquent',
'model' => 'User',
'table' => 'gebruikers',
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
'username' => 'gebruikersnaam',
'password' => 'wachtwoord',
);
Note: Input::get('wachtwoord') and Input::get('gebruikersnaam') are filled correctly by post in the controller. The md5 is correcly changed to the Laravel hash in my db so i cannot find the problem what i dealing with.
Note2: "gebruikersnaam" is dutch for username and "wachtwoord" is dutch for password
Note 3: i use Laravel 4
** EDIT **
Output $user
["attributes":protected]=> array(16) { ["id"]=> int(8681) ["gebruikersnaam"]=> string(22) "---" ["wachtwoord"]=> string(60) "$2y$10$i3bemDK9NzNf/E0jmliv/eBPrqhq/3s3WGPTX3h6WNCMlXcS5W51i" ["email"]=> string(22) "---" ["voornaam"]=> string(5) "Jelle" ["tussenvoegsel"]=> NULL ["achternaam"]=> string(4) "Pals" ["school_id"]=> int(110) ["telefoonnummer"]=> string(10) "0655684308" ["geslacht"]=> string(3) "man" ["geboortedatum"]=> string(19) "1990-03-22 09:00:00" ["groep_id"]=> int(8811) ["status"]=> string(1) "1" ["updated_at"]=> string(19) "2014-06-25 14:53:43" ["created_at"]=> string(19) "0000-00-00 00:00:00" ["remember_token"]=> string(0) "" }
**Found strange 000000 in updated_at **
I think the issue is that you're using the default Eloquent user settings (UserTrait) which assume that your password field is 'password' (see here), but you're using 'wachtwoord'. As such, logins fail due to the lack of a value in the password column (due to the lack of the column entirely) to test passwords on.
In case you're thinking "but I clearly specify the password column in my auth config!" that's unfortunately a bit of a red herring - that part of the config is for if you use the standard DB auth, whereas you are using Eloquent auth (notice how, in your config, you have driver set to eloquent?), so you need to specify these fields in your model as per the interface.
Luckily, a class's own implementation overrides that of a trait, so you can theoretically keep the trait on your model, and just override the getAuthPassword method.
That said, that trait (and the remindable one) does very much assume you're using English names everywhere, so it may be worth you removing the two traits entirely (UserTrait and RemindableTrait) and writing your own versions of the interface methods, as you'll likely see the same thing happen if/when you use "remember me" or "forgotten password".
Edit: initial suggestion:
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface
{
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'gebruikers';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('wachtwoord');
/**
* Override UserTrait#getAuthPassword
*/
public function getAuthPassword()
{
return $this->wachtwoord;
}
}
But, as I say, if you continue to use Dutch column names, you'll end up being better off dropping the traits entirely and implementing the methods yourself:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'gebruikers';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('wachtwoord');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->wachtwoord;
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken()
{
return $this->aandenken_onthouden; // okay I made this up based on Google translate and some guesswork, use your own version!
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
$this->aandenken_onthouden = $value;
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName()
{
return 'aandenken_onthouden';
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
Related
The default model "User" in laravel throws error when I tried to use it. What I tried is,
$user = new User();
$user->email = Input::get('email');
$user->password = Hash::make(Input::get('password'));
$user->name = "Blah Blah";
$user->access_type = "admin";
$user->access_status = 1;
$user->save();
and the error thrown is
Symfony \ Component \ Debug \ Exception \ FatalErrorException
Call to undefined method User::save()
What is the issue? I also tried User::all() to retrieve the values, which also throws error Call to undefined method User::all().
Update1:
Here is my model
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the token value for the "remember me" session.
*
* #return string
*/
public function getRememberToken()
{
return $this->remember_token;
}
/**
* Set the token value for the "remember me" session.
*
* #param string $value
* #return void
*/
public function setRememberToken($value)
{
$this->remember_token = $value;
}
/**
* Get the column name for the "remember me" token.
*
* #return string
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
Update2:
I tried writing another model names and class name as Users, which works perfectly. But for authentication, it must be the User table right?
The reason for the issue is autoloader load wrong "User" model. Please have a look at the "/vendor/composer/autoload_classmap.php" file. Inside the return array value for the key "User" must be $baseDir . '/app/models/User.php
return array(
...,
'User' => $baseDir . '/app/models/User.php',
...,
);
Maybe User is a reserved word, just give the model another name say UserTbl
Still didn't received any answer to my question. Anyways now I'm running it using the new model named Users with the same doubt in mind.
I'm new to laravel, so i started by creating a messaging application. User should be able to send message to each other. So i created migrations, seeds,models and also defined relationships in models. Everything was working fine. I was able to seed perfectly.
So i created a login page, applied validations. But now i'm unable to login.
Here is the route :
Route::group(array('prefix'=>'social'), function(){
Route::get('/', array('as' => 'loginformshow', 'uses' => 'LoginformController#showLogin'));
Route::post('loginform', array('as'=>'loginformdo', 'uses'=>'LoginformController#doLogin'));
Route::get('loggedin', array('as'=>'loggedin', 'uses'=>'LoginformController#loggedin'));
});
Here's the respective method in controller
public function doLogin(){
$rules = array('email'=> 'required|email', 'password'=>'required');
$validator = Validator::make(Input::all(), $rules);
if($validator->fails()){
return Redirect::to('social')->withErrors($validator)->withInput(Input::except('password'));
}else {
$userdata = array('email' => Input::get('email'), 'password' => Input::get('password'));
if(Auth::attempt($userdata)) {
return Redirect::route('loggedin');
}else echo "Invalid User";
}
}
Auth::attempt is returning false every time and so the output is Invalid User.
i used print_r to check the data received in $userdata and it's showing correct credentials.
Here's the User model:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
public function conversationsReply(){
return $this->hasMany('ConversationReply', 'user_id', 'id');
}
}
I want to use column email and password for login.
Password is hashed during registration and saved to the database ('driver' => 'database').
Email column is not primary key, but just unique.
AuthController.php:
// Get all the inputs
$userdata = array(
'email' => Input::get('username'),
'password' => Input::get('password')
);
// Declare the rules for the form validation.
$rules = array(
'email' => 'Required',
'password' => 'Required'
);
// Validate the inputs.
$validator = Validator::make($userdata, $rules);
// Check if the form validates with success.
if ($validator->passes())
{
// Try to log the user in.
if (Auth::attempt($userdata, true))
{
// Redirect to homepage
return Redirect::to('')->with('success', 'You have logged in successfully');
}
else
{
// Redirect to the login page.
return Redirect::to('login')->withErrors(array('password' => 'password invalid'))->withInput(Input::except('password'));
}
}
Anyway, I just got error:
ErrorException
Undefined index: id
It also shows me this:
public function getAuthIdentifier()
{
return $this->attributes['id'];
}
What I am doing wrong? Thanks
EDIT
User model:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
getAuthIdentifier is an interface method. GenericUser class is implementating that method and requires user id.
So check do you really have id attribute on your model.
In case this helps someone in the future here is how I resolved this. As #WereWolf suggested you do want to set
protected $primaryKey = 'id';
in your model, but your driver should also be 'eloquent' in your auth.php config.
'driver' => 'eloquent',
This will tell laravel to use your Eloquent model as the user object instead of the generic user object from the database table.
You most probably didn't assign your primary key in the user table, the ID should be primary key and also you may add following in your User model to specify your custom primary key:
protected $primaryKey = 'id';
Make sure that, the primary key in the user table matched with this ($primaryKey), means that, must be same.
In Laravel4,I have written the following code in routes but it always redirect me to login page.
I have googled and found it on stack overflow too and tried all solutions but not succeeded.I am sure it would be a silly mistake but kindly track it out.Thank You
Routes:
Route::post('login', function ()
{
$user = array(
'username' => Input::get('username'),
'password' => Hash::make(Input::get('password'))
);
/* Store entered username and password in an array named as 'user' */
print_r($user);
if (Auth::attempt($user))
{
return Redirect::route('home')->with('flash_notice', 'You are successfully logged in.');
/* Authentication Success!!..Redirect user to home page */
}
else
{
return Redirect::route('login')
->with('flash_error', 'Your username/password combination was incorrect.')->withInput();
/* Authentication failure!! lets go back to the login page */
}
});
User Model:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
// public $timestamps = false;
/**
* The primary key of the table.
*
* #var string
*/
protected $primaryKey = 'id';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
}
User Seeder:
<?php
class UserSeeder extends Seeder {
public function run()
{
DB::table('users')->delete();
return array('table'=>'users',
array(
'username' => 'admin',
'password' => 'admin'
),
);
}
}
When you ask the Auth class to attempt a login, you pass in the username and pass as it is. But if you look into the method, it will first hash the password to make it secure and then match it with database entry. When you are storing it, from your present implementation, its not hashed.
As suggested above, you should make this change in your seeder:
array(
'username' => 'admin',
'password' => Hash::make('password')
),
Although I am not very sure if the way you are using seeder is correct by syntax, but if it works, just hash the password there.
You should hash your password.
array(
'username' => 'admin',
'password' => Hash::make('password')
),
You can find more information in the docs.
This is routes file and $users shows the values but login fails
Route::post('login', function () {
$user = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
if(Auth::attempt($user))
{
return Redirect::to('profile')
->with('flash_notice', 'You are successfully logged in.');
}
else
{
// authentication failure! lets go back to the login page
return Redirect::route('login')
->with('flash_error', 'Your username/password combination was incorrect.')
->withInput();
}
});
Modal:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
}
When using the authentication mechanism provided by Laravel you should pass the following check list:
The database column where you store the password should be a string with a length of 60 characters.
The password should be stored encrypted, no plain. Since we are talking about BCrypt it has to be a value similar to: $2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu.
You have to configure the security mechanism by editing the file located app/config/auth.php.
After that, you will eventually have your problem solved.