Laravel Validation Check if password exists - php

I want to check if a password is correct of a particular user in the database. I want to use Laravel validation for this purpose
.
Here is my current code
$validator = $request->validate([
'password' => ['required',Rule::exists('users')->where(function ($query) { $query->where('id',Auth::id()); })]
]);
I think this generates the query
select count(*) as aggregate from `users` where `password` = 123 and id = 1))
What's missing is that I want this password (123) to be hashed to get checked properly.
Currently, I get the validation error
The selected password is invalid
Even I am entering the correct password

In this case you should create your own Validation Rule following this instructions
php artisan make:rule ValidatePassword
In the generated file, add the constructor method for receive the user you want to validate password against
public function __construct(User $user)
{
$this->user = $user;
}
You should write the logic for checking the password inside the passes method
public function passes($attribute, $value)
{
return Hash::check($value, $this->user->password);
}
Then, you can use it like
$validator = $request->validate([
'password' => ['required', new ValidatePassword(auth()->user())]
]);
Make sure to import User, ValidatePassword and Hash, I skipped that for brevity.

Related

php laravel Auth::attempt returns false

I am using laravel 6 and authenticating my users by Auth class. following code returns false always. what is problem guys ?
public function doLogin(Request $request){
$authenticate = Auth::attempt([
'email' => $request->input('email'),
'password' => $request->input('password'),
]);
if ($authenticate) {
return redirect('/');
}
}
You need to hash your password - by looking at your comment "password" => "123" - password is stored as plain text.
You can set up mutator in your User model to handle hashing automatically like so:
public function setPasswordAttribute(string $password): void
{
$this->attributes['password'] = Hash::make($password);
}
Make sure you import Illuminate\Support\Facades\Hash;
You can then add new user or update existing via tinker - this should convert plain text password to hash and your authentication should be validating.

Insert data and Login in laravel

I am working on an assignment in laravel where I've an Application form. I want to submit application form with email, mobileNo, customerId etc.
What I want is to insert form data into users table and then user will be logged in with auto generated password and redirect to Customer's dashboard. Where will be a modal will be open and ask for add password.
On the other hand there is also a login page from where user can login as usual. The login functionality is working properly.
Can someone help me to achieve the above functionality. Thanks in advance.
**Data is : **
email='user#gmail.com'
mobile='9875425698'
customerId='CI10001';
ApplicationForm Controller Where I am getting data successfully
class ApplicationForm extends Controller
{
public function saveApplicationForm(Request $request){
return $request;
}
}
Add user by submiting form
$password = bcrypt('secret'); //add here random password
$user = new User();
$user->email = 'xyz#gmail.com';
$user->mobileNo = '123456789';
$user->customerId = '1245';
$user->password = $password;
$user->save();
after you insert raw on user table login by user id without password
Auth::loginUsingId($user->id);
Auth::loginUsingId($user->id,true); // Login and "remember" the given user...
by otherwise login with email and password
Auth::attempt(['email' => $user->email, 'password' => $password], $remember);
all action do in one method(action)
Following my comment:
In the RegisterController (App\Http\Controllers\Auth)
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'institution' => $data['institution'],
'password' => 'NOT_SET',
]);
}
Then create a middleware (e.g. php artisan make:middleware Must_have_password)
namespace App\Http\Middleware;
use Closure;
use Auth;
class Must_have_password
{
/**
* Verify if password is set, otherwise redirect to password-set page.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$user = Auth::user();
if ($user && $user->password !== 'NOT_SET') {
return $next($request);
}
else return redirect('/set-password');
}
}
Of course, you then need to create a password setting view and hook that to the /set-password route. As I said in the comment, you want to make sure that /set-password route is well protected because you don't want people hijacking accounts that way. The good thing about this approach (using NOT_SET) is that people can always use the password_reset infrastructure to reset their password if they don't do it initially.
This is a bit hacky, but because Laravel always encrypts the passwords, there is no way the value can become NOT_SET in another way. Alternatively, you could add a boolean to your user-model (something like Must_Reset) that redirects to the password-reset page.
You can also hook in the password-reset functionality of Laravel, look for 'One Time Password Laravel' (e.g. here).

Laravel 5 / Spark - Pass data from form request to controller

Working in Laravel Spark and have a custom API endpoint that checks a user credentials but doesn't log them in, just returns the user data.
I have a form request that checks the email and password for being required and then I use
withValidator()
to run some more validation on the password.
public function rules()
{
return [
'email' => 'required|email|exists:users',
'password' => 'required'
];
}
public function withValidator($validator)
{
$validator->after(function ($validator) {
$user = User::where('email', $this->email)->first();
if ( $user && !Hash::check($this->password, $user->password) ) {
$validator->errors()->add('password', 'Incorrect password');
} else {
// Pass the user to the controller
}
});
}
In my controller I want to be able to return the user, but I dont want to run through the process of checking the hash etc.
I would simply like to be able to do:
return $request->user
Or similar.
Is there a way to do this?
Why not just do this in the controller?
$user = User::where('email', $request->email)->first();
If you put this after the validator, you already know the user is valid, otherwise the validator would fail before it got to that point.

How to login with hash class in Laravel 5.1

I want use hash class for hash my passwords.
because I want slat password with My policy.
I have controller like this:
public function postLogin(Request $request)
{
$rules = array(
'username' => 'required',
'password' => 'required|min:8'
);
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)
->withInput();
} else {
$user=User::where('username',$request['username'])->where('group_id',1)->get()->toArray();
$password=new PasswordController;
$request['password'] = $password->create_password_str($request['username'],$request['password']);
if(isset($user[0]['password'])&&Hash::check($request['password'], $user[0]['password'])){
return redirect('/dashboard');
} else {
return view('auth.login')->with('flag',5);
}
}
}
I use username after login like this
{{Auth::user()->username}}
show me error
Trying to get property of non-object
I add this code before redirect but dont work.
Auth::login($request['username']);
Because you do not use the laravel builtin function so it did not store the user in a SESSION and it throws an error while you try to fetch a user data which actually does not exists. Here's how to authenticate with laravel auth attempt function
if( Auth::attempt(['username' => $username, 'password' => $password]))
{
//redirect to dashboard
} else
{
//invalid credentials
}
Note : Even you do not need to convert your password to hash. laravel is intelligent enough to convert it to hash.
Update: If you want to use custom salt for your project you could checkout this link.

Laravel 5 two-way table login

I am trying to configure a laravel 5 app that will login users based on their username with password, if the username and password method fails the app will try to check the other table if the data in the username variable is available in my case their employee_id. So here is my code for logging users in with the conventional laravel method:
$authdetails = array(
'email' => $request->input('email'),
'password' => $request->input('password')
);
if (Auth::attempt($authdetails)) {
// Authentication passed...
return redirect()->to('/home');
}
else {
return back()->with('error', 'Invalid username or password')->withInput();
}
}
I have two tables inside the database. (1)users, (2)userdetails, the user table contains your standard laravel users default migration table, the userdetails table contains the details for the user. The first method of the login authentication uses the users table, the second method of login I want to implement if the first fails uses the userdetails table.
What I'm trying to do is if the first method of the login fails, it will search the other table for a value of the variable passed if there is then it will authenticate it.
If you have the employee_id column in your users table, then it's really easy. You just try to authenticate with both sets of credentials.
public function postLogin(Request $request) {
$this->validate($request, [
'usernameOrEmployeeId' => 'required',
'password' => 'required',
]);
// Attempt login via username
$credentials = [
'username' => $request->input('usernameOrEmployeeId'),
'password' => $request->input('password'),
];
if (Auth::attempt($credentials, $request->has('remember'))) {
return redirect()->intended($this->redirectPath());
}
// Swap username and employee_id
$credentials['employee_id'] = $request->input('usernameOrEmployeeId');
unset($credentials['username']);
// Attempt login via employee_id
if (Auth::attempt($credentials, $request->has('remember'))) {
return redirect()->intended($this->redirectPath());
}
// Login attempts failed
return redirect($this->loginPath())
->withInput($request->only('usernameOrEmployeeId', 'remember'))
->withErrors([
'usernameOrEmployeeId' => $this->getFailedLoginMessage(),
]);
}
If you don't have an employee_id column in your users table, then it's a bit more difficult. You would use the same code as above, except you would replace this part:
// Swap username and employee_id
$credentials['employee_id'] = $credentials['username'];
unset($credentials['username']);
with something like this:
// Find user_id by looking up the employee relationship
$employee = App\Employee::findOrFail($request->input('usernameOrEmployeeId'));
$credentials['id'] = $employee->user->id;
unset($credentials['username']);
Don't forget the unset(). It is important because if you leave username in the array, Laravel will try to authenticate with all 3 pieces of info and will always fail because we already know the username/password don't match.
Also, you don't have to use any third party libraries. This is a simple problem with a relatively simple solution.
If you want to login with two different table when first one is failed to authenticate.You have to use multiauth library Here and Here.
and then use like this.
$authdetails = array(
'email' => $request->input('email'),
'password' => $request->input('password')
);
if (Auth::user1()->attempt($authdetails)) {
// Authentication passed...
return redirect()->to('/home1');
}
if (Auth::user2()->attempt($authdetails)) {
// Authentication passed...
return redirect()->to('/home2');
}
else {
return back()->with('error', 'Invalid username or password')->withInput();
}
}

Categories