Laravel 4 Auth::attempt() always returns false - php

I'm trying the Laravel's Auth class but everytime i attempt to log in a user, the method returns false. Here's my code:
Routes.php
Route::get('new-user', function() {
return View::make('register');
});
Route::post('new-user', function() {
$name = Input::get('name');
$email = Input::get('email');
$password = Hash::make(Input::get('password'));
$user = new User;
$user->name = $name;
$user->email = $email;
$user->password = $password;
$user->save();
});
Route::get('login', function() {
return View::make('login');
});
Route::post('login', function() {
$user = array(
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password'))
);
if (Auth::attempt($user)) {
//return Redirect::intended('dashboard');
return "ok.";
} else {
return "Wrong.";
}
});
views/login.blade.php
{{ Form::open(array('url' => 'login', 'method' => 'post')) }}
<h1>Login:</h1>
<p>
{{ Form::label('email', 'Email: ') }}
{{ Form::text('email') }}<br />
{{ Form::label('password', 'Password: ') }}
{{ Form::password('password') }}<br />
</p>
<p>
{{ Form::submit('Login') }}
</p>
{{ Form::close() }}
config/auth.php
return array(
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users',
'reminder' => array(
'email' => 'emails.auth.reminder', 'table' => 'password_reminders',
),
);
The database has the email & password fields, and the password field is varchar(60).
Whenever i send the login info to /login it returns me "Wrong."
I really can't see whats wrong here?

Your code is bugging out because you are passing the wrong variables to Auth::attempt(). That method requires an array with keys username, password and optionally remember. In that light, your above code should be:
Route::post('login', function()
{
$credentials = [
'username' => Input::get('email'),
'password' => Input::get('password')
];
dd(Auth::attempt($credentials));
});
Hope that helps.
Also I'll give you snippets of extra code to improve your work flow. Route to store new user:
Route::post('register', function()
{
$input = Input::only(['username', 'email', 'password']);
// validate data
Eloquent::unguard();
$user = User::create($input);
Auth::loginUsingId($user->id);
return Redirect::to('dashboard');
});
Then in your user model add the method
public function setPasswordAttribute()
{
$this->password = Hash::make($this->password);
}
This way the password will be automatically hashed every time it's set

Don't hash the password before attempt:
$user = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
if (Auth::attempt($user)) {
//return Redirect::intended('dashboard');
return "ok.";
} else {
return "Wrong.";
}

this will not work because auth::attempt converts password to hash using bcrypt, and looks for that hash in users table to match.
in short the password should be a hash stored in database table for auth::attempt to work.
that is why your if() condition failing.
you can use bcrypt(password) to store password as hash in database and then use auth::attempt
below is from laravel docs
https://laravel.com/docs/5.2/authentication#authenticating-users
The attempt method accepts an array of key / value pairs as its first
argument. The values in the array will be used to find the user in
your database table. So, in the example above, the user will be
retrieved by the value of the email column. If the user is found, the
hashed password stored in the database will be compared with the
hashed password value passed to the method via the array. If the two
hashed passwords match an authenticated session will be started for
the user.
The attempt method will return true if authentication was successful.
Otherwise, false will be returned.

You should implement UserInterface class provided by laravel within your model class:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface
{
And remember that it has 2 abstract methods that you should declare at your model. You can follow original User.php model

Check your password Length. It must be 60 or higher in database.

Related

add in conditional to Laravel auth

In my users table I have role field which can be filled with any of admin, driver, petugas, rental. I want to let the user with role either admin or rental login, other than that the login system will deny the user.
I try to override the credentials() method in LoginController.php like below
protected function credentials(Request $request)
{
$field = $this->field($request);
return [
$field => $request->get($this->username()),
'password' => $request->get('password'),
'role'=>['admin', 'jasa_angkutan', 'rental']
];
}
but it's not working.. I truely have no idea how to achieve the requirement.
here's a dirty hack but at least works in my case.
protected function credentials(Request $request)
{
$field = $this->field($request);
$user = \App\User::where([
$field=>$request->get($this->username())
])->whereIn('role', [
'admin', 'jasa_angkutan', 'rental'
])->first();
if($user){
return [
$field => $request->get($this->username()),
'password' => $request->get('password')
];
}
return [];
}
before pass the credentials to auth method, I, first check if the user and role match the criteria. that's it.

Laravel 5.2 - Authenticated User to Change Password - Password Matching Issue after Update

So I'm having a rather odd issue. I've created a form that allows the user to change their password.
It does change their password. But it changes their password to something that Laravel can apparently not recognise.
So if I were to use "tinker" to manually update a password to something like "testing"; I'd be able to successfully change my password. However, once I'd changed the password to something (for e.g. 123456), the form wouldn't accept the password.
When I logout of the user and try and login with the new password; it wont let me login.
So clearly Laravel is not recognising the new password.
Code is here:
View:
<div class="panel panel-default">
<div class="panel-heading">Change Your Password</div>
{{ Form::open(array('url' => 'security/change_password')) }}
<div class="form-group">
{!! Form::label('current_password', 'Enter Current Password:') !!}
{!! Form::text('current_password', null, ['class'=>'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('password', 'Enter New Password:') !!}
{!! Form::text('password', null, ['class'=>'form-control']) !!}
</div>
<div class="form-group">
{!! Form::label('password_confirmation', 'Confirm New Password:') !!}
{!! Form::text('password_confirmation', null, ['class'=>'form-control']) !!}
</div>
<div class="form-group">
{!! Form::submit('Change Password', ['class' => 'btn btn-primary form-control']) !!}
</div>
{!! Form::close() !!}
</div>
Controller:
public function updatePassword(UserSecurityFormRequest $request)
{
$user = Auth::user();
$current_password = $request->input('current_password');
$new_password = $request->input('password');
if (Hash::check($current_password, $user->password)) {
$user->fill([
'password' => Hash::make($request->newPassword)
])->save();
}
else{
return ('Please enter the correct password');
}
}
I also attempted to set an attribute on password in the User..
public function setPasswordAttribute($password)
{
return $this->attributes['password'] = bcrypt($password);
}
that didn't work. (edit: I then removed the above attribute) If anything it prevented the registration form (as part of Laravel's Default Auth system) from creating a password that the login form recognises.
I've checked to make sure that the form is submitting the correct details and it is. I did this by dumping all the data from the form inputs when the form is submitted successfully.
User Model:
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\User as Authenticatable;
//use App\Http\Controllers\traits\HasRoles;
class User extends Authenticatable
{
/**
* 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', 'remember_token',
];
//If register dont work or passwords arent being recognised then remove the following:
/* public function setPasswordAttribute($password)
{
return $this->attributes['password'] = bcrypt($password);
}*/
//turns dates to carbon
protected $dates = ['created_at'];
//Creates Many to Many Relationship between Users table (and model) and Roles Table (and model)
public function roles()
{
return $this->belongsToMany(Roles::class);
}
//Checks for a specific role
public function hasRole($role)
{
if(is_string($role))
{
return $this->roles->contains('name', $role);
}
return !! $role->intersect($this->roles)->count();
}
//gives the user the role
public function assignRole($role)
{
return $this->roles()->save(
Roles::whereName($role)->firstOrFail()
);
}
//Checks whether the user has a role with that permission
public function hasPermission($permission)
{
return $this->hasRole($permission->roles);
}
public function owns($related)
{
return $this->id === $related->user_id;
}
}
As you can see, I've commented out the attribute setter for passwords so that shouldn't affect it. Yet it still does not work.
Any help would be appreciated.
Thank you.
EDIT
It is not working. Massive thanks to everyone who responded and for #Steve Bauman for allowing me to indentify my mistake
Working function:
public function updatePassword(UserSecurityFormRequest $request)
{
$user = Auth::user();
$hashed_password = Auth::user()->password;
$current_password = $request->input('current_password');
$new_password = $request->input('password');
if (Hash::check($current_password, $hashed_password)) {
$user->fill([
'password' => Hash::make($request->password)
])->save();
}
else{
return ('Please enter the correct password');
}
}
Found your issue:
public function updatePassword(UserSecurityFormRequest $request)
{
$user = Auth::user();
$current_password = $request->input('current_password');
$new_password = $request->input('password');
if (Hash::check($current_password, $user->password)) {
$user->fill([
// This should be $request->password, not `$request->newPassword`
'password' => Hash::make($request->newPassword)
])->save();
} else {
return ('Please enter the correct password');
}
}
The requested variable newPassword would be empty, that's why your passwords don't work. The request field your looking for is password.
This is due to your form field using password as the input name.
You make double password hasing, first in Hash::make($request->newPassword) second in setter bcrypt($password)
Remove one and everything should be okay.
Try to use this:
bcrypt($request->newPassword);

How to implement forgot password in cakephp3.x

I'm trying to implement a forgot password function in CakePHP 3.x.
I have created a form that accepts a user's email:
<?= $this->Form->create()?>
<div class="form-group">
<?= $this->Form->input('email', array('class' => 'form-group','autocomplete' => 'off' ,'required' => 'required'))?>
</div>
<div class="form-group">
<?= $this->Form->button('Reset Password', array('class' => 'form-group primary'))?>
</div>
<?= $this->Form->end()?>
In my controller I'm trying to find the user by the email, if the email exist then a random password will be generated and the password will be updated for that email id:
use Cake\ORM\TableRegistry;
use Cake\Auth\DefaultPasswordHasher;
public function forgotPassword($email = null){
if($this->request->is('post')) {
$email = $this->request->data['email'];
$emails = TableRegistry::get('Users');
$user = $emails->find()->where(['email' => $email ])->first();
if (!$user) {
$this->Flash->error(__('No user with that email found.'));
return $this->redirect(['controller' => 'Users','action' => 'forgotPassword']);
}else{
$random = 'a';
$hasher = new DefaultPasswordHasher();
$val = $hasher->hash($random);
$data = $this->Users->password = $val;
if ($this->Users->save($data)) {
$this->Flash->success(__('Password changed Succesfully.'));
return $this->redirect(['controller' => 'Users','action' => 'forgotPassword']);
}
}
}
}
You haven't actually stated a specific problem/question, but I think I might know what could help.
The whole DefaultPasswordHasher bit should be in the UsersEntity file, like in the tutorial: Blog tutorial
With the hashing properly placed in the entity like in the example it will automatically be called as soon as you use either PatchEntity or NewEntity (I think, confirmation please?).
Secondly, the $this->[model]->save() function works on entities, not just on data. So you would find the user's entity, patch the entity and then save it:
...} else {
$newpass = 'randomstring';
$user = $this->Users->PatchEntity($user, ['password' => $newpass]);
if ($this->Users->save($user)) ...

Login is Not Working Laravel 5

Hello friends I am using users table column like (USERNAME,EMAIL,PASSWORD)
if i am changing to column name as small letters is working fine. To Change column name as caps is not working give me any suggestion
This is my controller
public function postLogin(Request $request)
{
$this->validate($request, array('username' => 'required', 'password' => 'required'));
$credentials = $request->only('USERNAME', 'PASSWORD');
if (Auth::validate($credentials))
{
$user = Auth::getLastAttempted();
Auth::login($user, $request->has('remember'));
return redirect()->intended($this->redirectPath());
}
return redirect($this->loginPath())
->withInput($request->only('USERNAME', 'remember'))
->withErrors([
'username' => $this->getFailedLoginMessage(),
]);
}
Both user providers that you get with Laravel (EloquentUserProvider and DatabaseUserProvider) expect password to be stored in lowercase password field.
In order to make authentication work with PASSWORD field you need to do 2 things.
First, let providers know that user's password is stored in PASSWORD column. You can do this by implementing getAuthPassword method in your User model:
public function getAuthPassword() {
return $this->PASSWORD;
}
Secondly, password needs to be stored with password key in the credentials array you pass to Auth::validate(). You'll need to change the name of the name of the form field that user inputs password into to password OR create credentials array manually:
$credentials = [
'USERNAME' => $request->get('USERNAME'),
'password' => $request->get('PASSWORD'),
];

laravel 5.1 login not working

I used laravel 5.1 authentication for login . but Auth::attempt($credentials) returns false always!
I used the following route to create user:
Route::get('newuser', function () {
return User::create([
'username' => 'admin',
'email' => 'admin#gmail.com',
'password' => Hash::make('123'),
]);
});
I added a simple postLogin function to override this function in AuthController:
public function postLogin(Request $request) {
$credentials = $this->getCredentials($request);
if(Auth::attempt($credentials)) {
return 'ok';
}
return 'nok';
}
getCredentials is laravel function with this content:
protected function getCredentials(Request $request)
{
return $request->only($this->loginUsername(), 'password');
}
There could be multiple reasons for this thing.
I would suggest you to check the lenght of the password column in phpMyAdmin in your user table.
Change the password column to maximum lenght in database in the table where you are storing the password.
Another I would suggest you try with following code if it is working.
public function postLogin()
{
// Login credentials
$credentials = array(
'username' => 'admin#gmail.com',
'password' => '123',
);
// Authenticate the user
if (Auth::attempt($credentials))
{
return 'ok';
}
else{
return "failed";
}
Hope it would help.
Dont forget to change the password column length in database,Change it to maximum.
Change the password datatype to LONGTEXT with length to maximun or 1000.
Last and important is to delete all the records from the table and restart the process,because the priviously saved passed was saved with another lenght and beacuse of that the currunt hashed password does not matches the old one.
So truncate that table and try it again.

Categories