laravel 5 Authentication always return false - php

i have tried everything, i really don't know where i am doing wrong but each time i log in, it returns false.
here is the method to store users in the db:
public function store(CreateUserRequest $request)
{
$user = new User();
$password = str_random(10);
$password_hash = bcrypt($password);
$new_user = $user->create([
'first_name'=>$request->input('first_name'),
'last_name'=>$request->input('last_name'),
'email'=>$request->input('email'),
'fone_number'=>$request->input('fone'),
'password'=>$password_hash
]);
$new_user->permissions()->create(UserPermission::$default);
//send email to the user
Mail::send('admin.emails.auth.new_user',['new_user'=>$new_user,'password'=>$password],function($message) use ($new_user){
$message->to($new_user->email)
->from('lilgaetan88#gmail.com','Admin Pedagogia')
->subject("your password");
});
return redirect()->route('home')->with('Success',"mail sent");
}
the logincontroller
public function postLogin(LoginRequest $request){
$remember = ($request->has('remember')) ? true : false;
if(Auth::attempt($request->only(['email','password']),$remember)){
return redirect()->intended('/home');
}
return redirect()->route('login')->with('fail','email or password incorrect');
}
}
login.blade.php file:
<form class="login-form" action="{{route('post-login')}}" method="post">
#if(Session::has('fail'))
<div class="alert alert-danger">{{\Illuminate\Support\Facades\Session::get('fail')}}</div>
#endif
#if ($errors->has())
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
{{ $error }}<br/>
#endforeach
</div>
#endif
<div class="login-wrap">
<p class="login-img"><i class="fa fa-lock"> Login Page</i></p>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-envelope"></i></span>
<input type="text" name="email" class="form-control" placeholder="E-mail" autofocus>
</div>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-key"></i></span>
<input type="password" name="password" class="form-control" placeholder="Password">
</div>
<label class="checkbox">
<input type="checkbox" name="remember"> Se souvenir de moi
<span class="pull-right "> Mot de Passe Oublie?</span>
</label>
{!!Form::token()!!}
<button class="btn btn-primary btn-block" type="submit">Login</button>
</div>
</form>
when i dd(Hash::check($pssowrd,$new_user->password)), it returns always true, that means the hashed password was correct but the authentication still returns false

Try for remove bcrypt() method on line 6.
I think password hashing is automatic handled in laravel and therefore you don't need for bcrypt($password).

One possible Error would be, you are supposed send an Associative array of data to the attempt method; not an indexed array. So i guess it would work fine if you did like this,
Auth::attempt(['email' => $request['email'], 'password' => $request['password']], $remember))
Indexed and Associative Arrays in Php
Laravel Doc Auth::attempt()

Related

Why does Laravel login attempt redirects back to the login page?

Laravel redirect me back to the login page after each attempt to login. How do i fix this issue?
I've tried changing the session from 'file' to 'database' and clearing all the cache(both in the browser and in laravel, yet it's still redirects back to the login page)
Here is the web route:
// Login
Route::post("/profile/dashboard","LoginController#login")->name('login');
Here is my controller:
public function login(Request $req)
{
// validate form
$req->validate([
"email" => "required|email|max:255",
"password" => "required|max:16",
]);
$user = ["email" => $req->email, "password" => $req->password];
// Attempt to login
if (!Auth::attempt($user)) {
return back();
}
// Redirects to dashboard
return redirect()->route('dashboard');
}
Sorry for the poor formatting. Here is my view:
<form action="{{ url("/profile/dashboard") }}"
method="post" class="user">
{{ csrf_field() }}
<div class="form-group">
<input type="email" name="email" id="email" class="form-control
form-control-user" aria-describedby="emailHelp" placeholder="Enter Email Address...">
<label class="error" for="email">
#include("pages.errors.email")
</label>
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control form-control-user" placeholder="Password">
<label class="error" for="password">
<label class="error" for="password">
#include("pages.errors.password")
</label>
</label>
</div>
<div class="form-group">
<div class="custom-control custom-checkbox small">
<input type="checkbox" class="custom-control-input" id="customCheck">
<label class="custom-control-label form-check-label" for="customCheck">Remember Me</label>
</div>
</div>
<button type="submit" class="btn btn-outline-success btn-user btn-block text-uppercase">Login</button>
<hr>
<a href="index.html" class="btn btn-danger btn-google
btn-user btn- block text-uppercase">
<i class="fab fa-google"></i> Login with Google
</a>
</form>
I dont't if this will help but here is my session set to database:
'driver' => env('SESSION_DRIVER', 'database'),
No Error was generate. It redirects back to the login page without any given error.
https://laravel.com/docs/5.8/validation#quick-displaying-the-validation-errors
So, what if the incoming request parameters do not pass the given validation rules? As mentioned previously, Laravel will automatically redirect the user back to their previous location. In addition, all of the validation errors will automatically be flashed to the session.
Since you're not displaying the $errors variable, you're not getting any useful feedback. Try showing the value of $errors->all() in your form.

One login page for multiple clients

I had a laravel system built and trying to figure out how multiple clients can login using a single URL such as www.example.com/login
As the moment each user must have a unique url like below:
www.example.com/biz1/admin/login
www.example.com/biz2/admin/login
From what i can tell the code is getting the biz name from the url and adding it into the form, please see form below:
<form action="{{ route('business.admin.authenticate', ['bzname' => $bzname]) }}" method="post" >
{{ csrf_field() }}
<div class="form-group">
<label style="color: #fff" class="label">Email</label>
<div class="input-group">
<input style="color: #fff" type="text" class="form-control" placeholder="Email" name="email">
<div class="input-group-append">
<span class="input-group-text">
<i class="mdi mdi-check-circle-outline"></i>
</span>
</div>
</div>
</div>
<div class="form-group">
<label style="color: #fff" class="label">Password</label>
<div class="input-group">
<input style="color: #fff" type="password" class="form-control" placeholder="*********" name="password">
<div class="input-group-append">
<span class="input-group-text">
<i class="mdi mdi-check-circle-outline"></i>
</span>
</div>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary submit-btn btn-block">Login</button>
</div>
</form>
This form then pasts to the function in the controller which is below:
public function authenticate(Request $request, $bzname)
{
$business = Business::where('business_name', $bzname)->first();
$business_admin = BusinessAdmin::where('business_id', $business->id)->first();
if(isset($business_admin))
{
$user = User::findOrFail($business_admin->user_id);
if($user->email === $request->input('email'))
{
if (Auth::guard('business')->attempt(['email'=>$request->input('email'), 'password'=>$request->input('password')]))
{
$permissions = [];
session(['permissions' => $permissions]);
return redirect()->route('business.admin.dashboard', ['bzname' => $bzname]);
}
else
{
return redirect()->route('business.admin.login', ['bzname' => $bzname])->with('errorLogin', 'Ooops! Invalid Email or Password')->withInput();
}
}
else
{
return redirect()->route('business.admin.login', ['bzname' => $bzname])->with('errorLogin', 'Ooops! Pls Enter Correct Business')->withInput();
}
}
}
I'm thinking somehow in the $business parameter i need to get the bzname from the email linked to the client instead of getting it from the URL.
My knowledge is very basic at the moment and any advice is appreciated.
Thanks

How to validate bcrypt password in Laravel?

I have a change password form with fields for old and new password
The old password field is named old_password.
In my controller i am validating the passwords like this
$this->validate($request, [
'old_password' => 'required|min:6|exists:users,password',
'password' => 'required|min:6:max:30',
]);
But its not working as im comparing the old_password directly with password without function bcrypt().
So how can i compare the old_password field with the already stored bcrypted password in user field.
Note: i want to give the validation error back that password does not
match if it is different
This is how I would make such a function
The HTML form
<form action="{{ url('admin/admin-admin-password-update/'.$admin->id) }}" method="post">
{{ csrf_field() }}
<div class="form-group {{ $errors->has('new_password') ? 'has-error' : '' }}">
<label for="new_password" class="form-label">New Password (Minimum of 6 characters. No spaces.) <span class="required-alert">*</span></label>
<input type="password" class="form-control" name="new_password" id="new_password" />
#if ($errors->has('new_password'))
<div class="help-block">
{{ $errors->first('new_password') }}
</div>
#endif
</div>
<div class="form-group {{ $errors->has('confirm_password') ? 'has-error' : '' }}">
<label for="confirm_password" class="form-label">Confirm New Password <span class="required-alert">*</span></label>
<input type="password" class="form-control" name="confirm_password" id="confirm_password" />
#if ($errors->has('confirm_password'))
<div class="help-block">
{{ $errors->first('confirm_password') }}
</div>
#endif
</div>
<div class="form-group clearfix">
<button type="submit" class="btn btn-primary">Save New Password</button>
</div>
</form>
controller code
public function updatePassword(Request $request)
{
$this->admin = Auth::user();
$this->id = $this->admin->id;
$this->validate($request, [
'current_password' => 'required',
'password' => 'required|min:6',
'confirm_password' => 'required|same:password',
]);
if (Hash::check($request->input('current_password'), $this->admin->password)) {
$this->admin->password = Hash::make($request->input('password'));
$this->admin->save();
return redirect()->back()->with('success', 'Your password has been updated.');
} else {
return redirect()->back()->with('warning', 'The current password you provided could not be verified');
}
}
You need to compare the hash results of both old_password and the other password you wish to compare.
// when old_password is not encrypted but other_password is:
bcrypt('old_password') === hash_of_other_password
One way of doing so with $this->validate and not writing custom rules would be to use $request->merge(). That way you can use the confirmed rule or even exists if you have the hashed value stored in your database.

Update the password value only when i change the password or else it retain the same value

I am trying to change the password value by getting old password it working fine but what my problem is when i try to update my field it save the new password value as empty(because i leave this field empty) i want to update the new password only when i change the new password value or else it maintain the current password in the new password field
here is inside my controller
public function profileupdate(Request $request,$id)
{
if(Auth::Check())
{
$request_data = $request->All();
$validator = $this->validator($request_data);
if($validator->fails())
{
$this->throwValidationException($request, $validator);
}
else
{
$current_password = Auth::User()->password;
if(Hash::check($request_data['current-password'], $current_password))
{
$user_id = Auth::User()->id;
$admin = Admin::find($user_id);
$admin->update([
'name'=>$request['name'],
'job_title'=> $request['job_title'],
'email'=>$request['email'],
'phone_number'=>$request['phone_number'],
'password'=> Hash::make($request['password']),
]);
return redirect('/admin/profile')
->with('message', 'Admin Profile updated successfuly!');
}
else
{
return redirect('/admin/profile')
->with('password', 'Please enter correct password!');
}
}
}
else
{
return redirect()->to('/');
}
}
Inside my view
<div class="control-group{{ $errors->has('current-password') ? ' has-error' : '' }}">
<label class="control-label"> Current Password:</label>
<div class="controls">
<input type="password" class="form-control" id="current-password" name="current-password" placeholder="Password">
#if(Session::has('password')) <span class="help-inline"> <strong>{{Session::get('password')}} </strong></span> #endif
#if ($errors->has('current-password'))
<span class="help-inline">
<strong>{{ $errors->first('current-password') }}</strong>
</span>
#endif
</div>
</div>
<div class="control-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label class="control-label"> New Password:</label>
<div class="controls">
<input type="password" class="form-control" id="password" name="password" placeholder="Password">
#if ($errors->has('password'))
<span class="help-inline">
<strong>{{ $errors->first('password') }}</strong>
</span>
#endif
</div>
</div>
<div class="control-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
<label class="control-label">Confirm Password:</label>
<div class="controls">
<input type="password" class="form-control" id="password_confirmation" name="password_confirmation" placeholder="Re-enter Password">
#if ($errors->has('password_confirmation'))
<span class="help-inline">
<strong>{{ $errors->first('password_confirmation') }}</strong>
</span>
#endif
</div>
</div>
Simply build the array which updates the values dynamically instead of statically. The majority of the array is still static, but the password is now dynamically added, depending of there was a value passed to the password field in your form.
// Values which are always updated
$update_values = [
'name'=>$request['name'],
'job_title'=> $request['job_title'],
'email'=>$request['email'],
'phone_number'=>$request['phone_number']
];
// If the password-field isn't empty, we add it to the values that are updated
if (!empty($request['password']))
$update_values['password'] = Hash::make($request['password']);
// Execute the update
$admin->update($update_values);

Laravel 5 Add errors in an array using After Validation Hook

I'm trying to add a function in my app where users are allowed to change their account password. I have three fields and my view looks like this:
<form class="form" role="form" action="{{ url('users/updatePassword') }}" method="post">
{{ csrf_field() }}
<div class="form-group label-floating {{ $errors->has('oldpassword') ? 'has-error' : '' }}">
<label class="control-label" for="oldpassword">Old Password</label>
<input type="password" name="oldpassword" class="form-control">
#if ($errors->has('oldpassword'))
<span class="help-block">
<strong>{{ $errors->first('oldpassword') }}</strong>
</span>
#endif
</div>
<div class="form-group label-floating {{ $errors->has('newpassword') ? 'has-error' : '' }}">
<label class="control-label" for="newpassword">New Password</label>
<input type="password" name="newpassword" class="form-control">
#if ($errors->has('newpassword'))
<span class="help-block">
<strong>{{ $errors->first('newpassword') }}</strong>
</span>
#endif
</div>
<div class="form-group label-floating">
<label class="control-label" for="newpassword_confirmation">Confirm Password</label>
<input type="password" name="newpassword_confirmation" class="form-control">
</div>
<div class="form-group">
<button class="btn btn-raised btn-primary">Change</button>
</div>
</form>
Firstly, I want to check if all fields are completely filled up and for that I used Validator. And then check if the oldpassword is match from the database so I use if (Auth::attempt(array('password' => $request->oldpassword))) condition. I also found in the laravel 5.2 documentation the After Validation hook. I don't know what is wrong but it seems it don't validates the oldpassword field when I typed a wrong password.
My controller:
$validator = Validator::make($request->all(), [
'oldpassword' => 'required|max:255',
'newpassword' => 'required|min:6|max:255|confirmed',
]);
$validator->after(function($validator) use($request) {
if (Auth::attempt(array('password' => $request->oldpassword))) {
$validator->errors()->add('oldpassword', 'Old password dont match in our database.');
}
});
if ($validator->fails()) {
// Toastr
$title = "Oops!";
$message = "Please make sure to fill all required fields.";
$options = [
'progressBar' => false,
'positionClass' => 'toast-top-right',
'timeOut' => 6000,
];
Toastr::error($message, $title, $options);
return redirect()->back()
->withErrors($validator);
} else {
return 'success'; // for testing only
}
Any idea regarding this?
According to your code when you enter correct oldpassword you get the error. So change if(Auth::attempt..... to if(!Auth:attempt.... And also if you use Auth:attempt you have to logout user again(this method also requires unique field like username or email to identify the user). so it's better if you use following method
if (!\Hash::check($request->get('oldpassword'), \Auth::user()->password)) {
$validator->errors()->add('oldpassword', 'Old password dont match in our database.');
}

Categories