Hi i'm new to laravel and was trying to use the auth system.
the problem i'm having is that when verifying the users username and password by auth::attemp() I end up with a 'whoops something went wrong page' but only when there is a known username being specified. When i'm inputting an unkown username i get the expected error page.
i've created an user by:
// add user
$user = new User;
$user->username = 'John';
$user->password = Hash::make('Doe');
$user->email = 'info#mail.com';
$user->save();
the route i've created for the post method looks like this:
Route::post('login', function(){
$credentials = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
// check credentials
if (Auth::attempt($credentials)) {
// go to index if login is successful
return Redirect::to('/');
}
// fail
return Redirect::to('login')->with('error' , 'Wrong username or password');
});
Now as i've said the error message is being shown if I specify an username wich is not (in this case) 'John'. when is do use 'John' I end up with an error no matter the password is correct or incorrect.
my question: What am i doing wrong here? and how to fix it?
It turned out to be a really stupid mistake. I edited the User model (app/models/User.php), this was causing the problem. I've reverted back to the original and everything works fine now!
Thanks for the help guys!
Related
I'm trying to write a test to assert that my login page displays an error when the user enters an incorrect username or password.
#if ($errors->any())
<p>Looks like you’ve entered the wrong username or password.
<a href="{{route('password.request')}}">
Click here</a> to reset your password“ </p></div>
#endif
The functionality is working fine and I can see the errors on page, but for some reason, I can't get my test to pass.
->assertSessionHasErrors() is working fine, while ->assertSeeText() is not detecting the error messages in text.
`
public function userSeesErrorMessage() {
$user = factory('App\User')->create([
'password' => bcrypt($password = 'test'),
]);
$response = $this->followingRedirects()
->post('/login', [
'email' => $user->email,
'password' => 'incorrectPassword'
]);
$response->assertSeeText('Looks like you’ve entered the wrong username or password. Click here to reset your password');
}`
The response seem to contain the whole document's HTML, except for the part about the errors.
Any help would be much appreciated.
There might be a few reasons why this does does not work. Easiest thing you could do is to set a header for a referer. This way the validation will know where to redirect you back, because currently you're not submitting a form and the redirect is sending you to a page where you might not display the errors:
$response = $this->followingRedirects()
->post(
'/login',
[
'email' => $user->email,
'password' => 'incorrectPassword'
],
['referer' => '/login']
);
Another issue might be that the session errors are lost within the redirects, where you can try following the redirect separately:
$r = $this->post('/login', [
'email' => $user->email,
'password' => 'incorrectPassword'
]);
$r->assertStatus(302);
$r->assertSessionHasErrors('email');
$r = $this->followRedirects($r);
$r->assertSeeText('Looks like you’ve entered the wrong username or password. Click here to reset your password');
In my database password column name is "new_password".
then when I try to log, it says Undefined index: password.
But if password column name is "password" it works properly. I need to use previous column name.
How can I fix this?
$credentials = array(
'user_name' => Input::get('username'),
'new_password' => Input::get('password')
);
$user = Auth::attempt($credentials);
Hello, Thisaru
If you need to use your password field as new_password
1) First thing is laravel password field by default set password into your model. So If you change the password as new_password add this line in your Model
protected $primaryKey = 'new_password';
I hope this code help to solve your problem
I'm trying to make my first Moodle auth extension where I want to confirm and login users directly after signup.
I've changed the user_signup function in the "email" auth plugin like this:
\core\event\user_created::create_from_userid($user->id)->trigger();
$DB->set_field("user", "confirmed", 1, array("id"=>$user->id));
$user = get_complete_user_data('username', $username);
$DB->set_field("user", "firstaccess", time(), array("id"=>$user->id));
$DB->set_field("user", "lastlogin", 0, array("id"=>$user->id));
update_user_login_times($user);
complete_user_login($user);
redirect("$CFG->wwwroot/enrol/index.php?id=2");
It works so far as the user gets signed up and confirmed. But as for the login I get the following error:
core\session\manager::login_user() must be an instance of stdClass, boolean given
I might be acting stupid here, but I don't know how I could login the new user here. Any help would be very much apprechiated. Thanks!
After Creating user account get username and password that you have entered and then implement like this.
if ($user = authenticate_user_login($username, $password)) {
/// Let's get them all set up.
complete_user_login($user);
redirect($CFG->wwwroot . 'URL you want');
}
I need to do some extra checks on a user, I would like to get the user by username and password.
Firstly:
Is there a built in function that gets a user by username and password without authenticating them?
Secondly:
If the above is no, then how do I correctly hash the password, because if I use Hash::make( $password ) and then compare to the database, it is not the same... You would usually use Hash::check but I need to actually get the user by username and password.
In Laravel 5.2
You can use Auth::once($credentials) to validate credentials and thereafter Auth::getUser(); to get the user.
$credentials = Request::only('username', 'password');
if(!Auth::once($credentials)) {
// Invalid user credentials; throw Exception.
}
$user = Auth::getUser();
First:
If you want to check if user data to authentication is correct you can use:
if (Auth::validate($credentials))
{
//
}
But if you want to get user from database with user and password, you can use:
$user = User::whereName($username)->wherePassword(Hash::make($password))->first();
Second
To store password in database you should use Hash::make($password) as you showed and it works without any problems. Using Auth::validate should solve the issue.
Yes, there is a built in function you should use. I recommend you to read the docs. But here's a good example, it's pretty self-evident:
$input = array(
'username' => Input::get('username'),
'password' => Input::get('password'),
);
$remember = (boolean)Input::get('remember'); //'Remember me' checkbox
if (Auth::attempt($input, $remember)) {
return Redirect::intended('dashboard')->with("success", "You're logged in!"); //Redirect the user to the page intended to go to, with the dashboard page as default
}
Registering a user looks something like this:
$input = array(
'username' => Input::get('username'),
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password')) //Encrypt password
);
$user = User::create($input);
I also recommend you to read about input validation. I hope this helps, good luck.
Edit: I didn't read the "without authenticating them" part. You should use Auth::validate($input) as Marcin already explained.
Laravel 5.7
To check a users credentials without logging them in, I had to do this:
$user = User::whereEmail($request->email)->first();
$user = password_verify($request->password, optional($user)->getAuthPassword()) ? $user : false;
Laravel auth validation makes use of https://www.php.net/manual/en/function.password-verify.php
This question already has answers here:
laravel 4 custom named password column
(4 answers)
Closed 8 years ago.
I would like to change password field in database when using Laravel authentication. I want my column in users table has name passwd and not password. I tried to run something like this:
Auth::attempt(array(
'user_name' => 'admin',
'passwd' => 'hardpass',
));
but it doesn't work.
I also tried to add in User model the following function:
public function getAuthPassword() {
return $this->passwd;
}
but it also changes nothing. User is still not being authenticated. Is it possible in Laravel to change password field name in database ?
Information
You can change easy all other fields in database and use them for authentication. The only problem is with password field.
In fact password field is in some way hard coded in Laravel (but not the way many think) so you cannot just pass array as you passed in your question.
By default if you pass array to attempt (and probably other Auth functions like validate or once) if you do it this way:
Auth::attempt(array(
'user_name' => 'admin',
'password' => 'hardpass',
));
default Eloquent driver will run the following query:
select * from `users` where `user_name` = 'admin' limit 1;
After getting this data from database it will compare password you gave with password property for User object that was created.
But if you simply use:
Auth::attempt(array(
'user_name' => 'admin',
'passwd' => 'hardpass',
));
the following query will be run:
select * from `users` where `user_name` = 'admin' and `passwd` = 'hardpass' limit 1;
and no user will be found in database (in passwd you store hashed password). This is because Eloquent removes from query password but use any other data to run query. Also if you try here to use 'passwd' => Hash:make($data['password']) although user will be found, comparing password won't work.
Solution
Solution is quite easy. You need to run Auth::attempt like this:
Auth::attempt(array(
'user_name' => 'admin',
'password' => 'hardpass',
));
As you see you still pass password as key (although this column doesn't exits in users table) because only this way Eloquent driver won't use it for building query.
Now in User model (app/models/User.php) file you need to add the following function:
public function getAuthPassword() {
return $this->passwd;
}
As you see you use here the column that really exists in database: passwd.
Using it this way you can have column with password named anything you want and you can still use default Eloquent driver for it.
Sample data to test
I've created very simple test for it.
You just need to replace your app/routes.php file with the following:
Route::get('/', function () {
if (Auth::check()) {
echo "I'm logged in as " . Auth::user()->user_name . "<br />";
echo "<a href='/logout'>Log out</a>";
} else {
echo "I'm NOT logged in<br />";
Auth::attempt(array(
'user_name' => 'admin',
'password' => 'hardpass',
));
if (Auth::check()) {
echo "Now I'm logged in as " . Auth::user()->user_name . "<br />";
echo "<a href='/logout'>Log out</a>";
} else {
echo "I'm still NOT logged in<br />";
}
}
});
Route::get('/logout', function () {
Auth::logout();
return "You have been logged out";
});
Route::get('/db', function () {
if (!Schema::hasTable('users')) {
Schema::create('users', function ($table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('user_name', 60)->unique();
$table->string('passwd', 256);
$table->rememberToken();
$table->timestamps();
});
DB::table('users')->insert(
[
[
'user_name' => 'admin',
'passwd' => Hash::make('hardpass'),
]
]
);
}
echo "Table users has been created";
});
Create empty database and set connection data in app/config/database.php
Now you can run /db url for example http://localhost/yourprojectname/db just to create users table.
Now you can run / url for example http://localhost/yourprojectname/ - as you see user is logged in even if in users table in database you don't have any password column (data for authentication has been passed as strings without any forms but of course in real application you will add them) . You can run this url once more time - as you see user is still logged so it is working as expected.
If you click on Log out link, you will be logged out
Laravel 5 changes for above
This solution was tested in Larave 4.2.9 (everything as above) and also in Laravel 5. In Laravel5 everything works the same but you need of course edit files in different paths:
User model is in app/User.php file
routes are in app/Http/routes.php file
Database config file is in config/database.php file