Laravel 5.8 change password functionality - php

I'm currently trying to make change password functionality to my user profile all my inputs are submitted to the controller, but I think there might be something wrong with my function logic maybe?
Tried dumping request on function and dump was successfully returned. But when wrapping a validation variable around a validation process, the dump was not returned. The request redirects back to the profile page with form data.
Controller
public function updatePassword(Request $request)
{
$this->validate($request, [
'old_password' => 'required',
'new_password' => 'required|confirmed',
'password_confirm' => 'required'
]);
$user = User::find(Auth::id());
if (!Hash::check($request->current, $user->password)) {
return response()->json(['errors' =>
['current' => ['Current password does not match']]], 422);
}
$user->password = Hash::make($request->password);
$user->save();
return $user;
}
View
<form method="POST" action="{{ route('update-password') }}">
#csrf
#method('PUT')
<div class="form-group row">
<label for="old_password" class="col-md-2 col-form-label">{{ __('Current password') }}</label>
<div class="col-md-6">
<input id="old_password" name="old_password" type="password" class="form-control" required autofocus>
</div>
</div>
<div class="form-group row">
<label for="new_password" class="col-md-2 col-form-label">{{ __('New password') }}</label>
<div class="col-md-6">
<input id="new_password" name="new_password" type="password" class="form-control" required autofocus>
</div>
</div>
<div class="form-group row">
<label for="password_confirm" class="col-md-2 col-form-label">{{ __('Confirm password') }}</label>
<div class="col-md-6">
<input id="password_confirm" name="password_confirm" type="password" class="form-control" required
autofocus>
</div>
</div>
<div class="form-group login-row row mb-0">
<div class="col-md-8 offset-md-2">
<button type="submit" class="btn btn-primary">
{{ __('Submit') }}
</button>
</div>
</div>
</form>
The result should return 422/error message at least into the console when 'Current password' is wrong, not just redirect back to view and when the password is correct then return 200/success message (not implemented yet.) to console or view.

try this
public function updatePassword(Request $request){
if (!(Hash::check($request->get('old_password'), Auth::user()->password))) {
// The passwords not matches
//return redirect()->back()->with("error","Your current password does not matches with the password you provided. Please try again.");
return response()->json(['errors' => ['current'=> ['Current password does not match']]], 422);
}
//uncomment this if you need to validate that the new password is same as old one
if(strcmp($request->get('old_password'), $request->get('new_password')) == 0){
//Current password and new password are same
//return redirect()->back()->with("error","New Password cannot be same as your current password. Please choose a different password.");
return response()->json(['errors' => ['current'=> ['New Password cannot be same as your current password']]], 422);
}
$validatedData = $request->validate([
'old_password' => 'required',
'new_password' => 'required|string|min:6|confirmed',
]);
//Change Password
$user = Auth::user();
$user->password = Hash::make($request->get('new_password'));
$user->save();
return $user;
}

Laravel 5.8
Include this function in a controller:
public function updatePassword(Request $request)
{
$request->validate([
'password' => 'required',
'new_password' => 'required|string|confirmed|min:6|different:password'
]);
if (Hash::check($request->password, Auth::user()->password) == false)
{
return response(['message' => 'Unauthorized'], 401);
}
$user = Auth::user();
$user->password = Hash::make($request->new_password);
$user->save();
return response([
'message' => 'Your password has been updated successfully.'
]);
}
Don't forget to send new_password_confirmation as a parameter too, because when we use the validation rule confirmed for new_password for example, Laravel automatically looks for a parameter called new_password_confirmation in order to compare both fields.

You are validating request fields old_password, new_password and password_confirm here:
$this->validate($request, [
'old_password' => 'required',
'new_password' => 'required|confirmed',
'password_confirm' => 'required'
]);
however your are using request fields current and password to verify current password and set a new one:
if (!Hash::check($request->current, $user->password)) {
// ...
$user->password = Hash::make($request->password);
Validated fields and used fields should be the same.

Related

How do I redirect to another page after form submission in Laravel

form
When i submit the form it redirects back to the form itself, can anyone help me?
<form action="/jisajili" method="POST">
#csrf
<div class="card-panel z-depth-5">
<h5 class="center red-text">Jiunge Nasi</h5>
<div class="input-field">
<i class="material-icons prefix">account_circle</i>
<input type="text" name="username" class="validate">
<label>Jina lako</label>
</div>
<div class="input-field">
<i class="material-icons prefix">phone</i>
<input type="number" name="phone" class="validate">
<label>Nambari ya simu</label>
</div>
....
</p>
<input type="submit" name="submit" value="Jiunge" class="btn left col s12 red">
Controller
class registration extends Controller{
public function create(){
return view('jisajili.jiunge');
}
public function store(Request $request){
$reg = new regist;
$reg->jina = $request->input('username');
$reg->simuNumber = $request->input('phone');
$reg->email = $request-> input('email');
$reg -> password = bcrypt($request->input('password'));
$cpassword = $request -> input('cpassword');
$reg->save();
$validated = $request->validate([
'name' => 'required|unique:posts|max:10',
'body' => 'required',
]);
return redirect('home');
}
}
What I would do is first check for the data requirements before you add the object to the database. Also I would add the columns of the models into the Model file to use the Object::create function with an array parameter.
I recomment to use routing in your blade file. I noticed you used action="/route". What you want to do is naming your routes with ->name('route_name') in the route files. To use them in your blade files with the global route function route="{{ route('route_name') }}".
<?php
class PostController extends Controller
{
public function index()
{
return view('post.create');
}
public function store(\Illuminate\Http\Request $request)
{
$validator = Validator::make(
$request->all(),
[
'name' => 'required|unique:posts|max:10',
'body' => 'required'
]
);
// Go back with errors when errors found
if ($validator->fails()) {
redirect()->back()->with($validator);
}
Post::create(
[
'name' => $request->get('name'),
'body' => $request->get('body')
]
);
return redirect()
->to(route('home'))
->with('message', 'The post has been added successfully!');
}
}
What you can do after this is adding custom errors into the controller or add them into your blade file. You can find more about this in the documentation of Laravel.
it redirects you back because of validation error.
change password confirmation name from cpassword into password_confirmation as mentioned in laravel docs
https://laravel.com/docs/7.x/validation#rule-confirmed
update your controller into:
public function store(Request $request){
$validated = $request->validate([
'username' => 'required',
'phone' => 'required',
'email' => 'required',
'password' => 'required|confirmed'
]);
$reg = new regist;
$reg->jina = $request->input('username');
$reg->simuNumber = $request->input('phone');
$reg->email = $request-> input('email');
$reg -> password = bcrypt($request->input('password'));
$reg->save();
return redirect('home');
}
in your blade add the following to display validation errors:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif

Difficulty in changing old email to new email in Laravel

I'm having a difficulty to change the current user's email to a new email which is user input and the email's validation. EDITED
Here's my controller
public function changeuser(Request $request){
$id = Auth::user()->id;
$change_user = User::find($id);
$valid = validator($request->only('oldpass', 'newpass', 'confirmpass'), [
'olduser' => 'required|email|max:255|exists:users',
'newuser' => 'required|email|max:255|different:olduser'
], [
'newuser.required_with' => 'Choose different email.'
]);
if ($valid->fails()) {
return redirect('/manageaccount')->with('message','Failed to update email');
}
$change_user->email = $request->input('newuser');
$change_user->save();
return redirect('/manageaccount')->with('message', 'email changed successfully');
}
my blade.php which is in modal
<div class="thirdea" id="thirdea">
<label><p class="small Montserrat">Enter Old Username</p></label>
<input type="text" class="form-control small Montserrat" name="olduser" value="" id="olduser">
<label><p class="small Montserrat"> New Username</p></label>
<input type="text" class="form-control small Montserrat" name="newuser" value="" id="newuser">
</div>
my route
Route::post('/changeuser/','UserController#changeuser');
In case of update user you can try validations for email like this :
$validate = $request -> validate([
'newuser' => 'required|unique:users,email,'.$user->id
]);

Displaying laravel error messages on redirect

I have a form which i am hoping to use to insert some data to mysql. I have setup the validator like this
public function insert_post(){
$rules = array(
'model' => 'required',
'country' => 'required',
'engine' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
// get the error messages from the validator
$messages = $validator->messages();
echo '<pre>';
print_r($messages);
echo '</pre>';
return Redirect::to('create-posts')
->withErrors($validator);
}
else {
$i = new Text;
$i->model = request('model');
$i->country = request('country');
$i->engine = request('engine');
$i->save();
return redirect('/');
}
}
My create-posts route looks like this.
public function create_post(){
return view('create-posts');
}
However, its not displaying the error since i think i am loading a fresh create-posts and the validator messages are lost.
view code
<div class="form-group">
<label for="inputEmail" class="control-label col-xs-2">Model</label>
<div class="col-xs-10">
<input type="text" class="form-control" id="inputEmail" name="model" placeholder="Model">
#if ($errors->has('model')) <p class="help-block">{{ $errors->first('model') }}</p> #endif
</div>
</div>
Is that what's the cause?.
In case you want to return to the last view, you can use:
return Redirect::back()->withErrors($validator);
Instead of return Redirect::to('create-posts')->withErrors($validator);.

Laravel 5 password reset not working

I am working on laravel 5 eCommerce web portal.
I am having an issue when the user updates the password using the ready made scripts.
The issue is that I can send the link to the customer perfectly without any issue and the customer can change his password also. But when logged out and re-logging in, I get the error as Invalid credentials.
In my routes.php, I have this:
Route::controllers([
'auth' => 'Auth\AuthController',
'password' => 'Auth\PasswordController',
]);
This is the login page:
<form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
<label class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input type="email" class="form-control" name="email" value="{{ old('email') }}">
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password">
</div>
</div>
<div class="form-group">
<div class="col-md-4"></div>
<div class="col-md-4">
Forgot Password
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<button type="submit" class="btn btn-primary btn-block">Login</button>
</div>
</div>
</form>
I cannot login again after I am logged out once the password has been reset.
EDIT 1:
When the login button is clicked on the login form page, the postLogin method is called. Here's the code
public function postLogin( Request $request ) {
$this->validate( $request, [
'email' => ['required', 'exists:users,email,role,customer'],
'password' => 'required'
]);
$credentials = $request->only('email', 'password');
if ( \Auth::attempt($credentials) ) {
\Session::flash('logged_in', 'You have successfully logged in.');
return redirect('/');
}
return redirect('/login')->withInput($request->all())->withErrors(['email' => 'Invalid Email Address Or Password']);
}
EDIT 2:
I just realize that login is not checking for the hash and hence returning false, on doing dd(\Hash::check($request->password, $user->password)), after updating the password and re-logging in. What could be the issue with this ?
Where have I made mistake ? Kindly guide me.
Thanks in advance.
P.S.: I am using the defaults only to update the password, rest all, I have made the controllers and models which are all working fine without any issue.
I stumbled upon this as well and found the answer here, just adding this for future reference..
The reason is that as soon as you add the setPasswordAttribute method on your User model, the password is hashed twice when using the built-in password reset functionality of Laravel. As explained on the Laracast page, all it needs is a check for an already hashed password, eg:
// Add Hash facade
use Illuminate\Support\Facades\Hash;
class User extends Authenticatable
{
// ...
/**
* Automatically hash password
*
* #param String $value The password, maybe hashed already
*
* #return string|null
*/
public function setPasswordAttribute($value)
{
if ($value) {
$this->attributes['password'] = Hash::needsRehash($value) ? Hash::make($value) : $value;
}
}
}
If the new password does not work after changing then something goes wrong when changing the password.
Most likely suspect is the encryption. It can be possible that you are not using the Hash::make($password) and saving it in plaintext format.
You can doublecheck if the hash is saved correctly to DB with function Hash::check($password, $hash);
During the login you can check the password as
public function postLogin( Request $request ) {
$user=User::where('email', $request->email);
Log::debug("Testing $request->password $user->password ". Hash::check($request->password, $user->password));
}
If the Hash::check is false then something went wrong when saving new password. $user->password must be in hashed form.

redirect loop error laravel auth

hi im trying to make a good user auth form but i ve have had some problems , so first i tried this :
Route::get('login', function()
{
/* Get the login form data using the 'Input' class */
$userdata = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
/* Try to authenticate the credentials */
if(Auth::attempt($userdata))
{
// we are now logged in, go to admin
return Redirect::to('home');
}
else
{
return Redirect::to('login');
}
});
and this is the form blade page :
{{ Form::open(array('url' => 'login', 'class' => 'form-horizontal')) }}
<div class="control-group">
<label class="control-label" for="username"></label>
<div class="controls">
<input id="username" name="username" type="text" placeholder="" class="input-xlarge" required="">
</div>
</div>
<!-- Password input-->
<div class="control-group">
<label class="control-label" for="password"></label>
<div class="controls">
<input id="password" name="password" type="password" placeholder="" class="input-xlarge" required="">
</div>
</div>
<!-- Button -->
<div class="control-group">
<label class="control-label" for="submit"></label>
<div class="controls">
<button id="submit" name="submit" class="btn btn-inverse"></button>
</div>
</div>
</fieldset>
and it gave me the redirect loop error
and then i tried this :
Route::get('login', function()
{
/* Get the login form data using the 'Input' class */
$user = new User;
$log = array(
$user -> username = Input::get('username'),
$user -> password = Input::get('password')
);
/* Try to authenticate the credentials */
if(Auth::attempt($log))
{
// we are now logged in, go to admin
return Redirect::to('home');
}
else
{
return Redirect::to('login');
}
});
and it gives me :
SQLSTATE[42S22]: Column not found: 1054 Unknown column '0' in 'where clause' (SQL: select * from `users` where `0` is null and `1` is null limit 1)
does anyone knows whats the problem?
first code should have worked perfectly but why redirect error?
Firstfully, change your route names, to:
Route::get('login', function(){}); And Route::get('sign-in', function(){});
Get auth page:
Route::get('login', function()
{
return View::make('your-auth-view');
}
And your sign-in handler should looks like:
Route::get('sign-in', function(){
$userdata = array(
'username' => Input::get('username'),
'password' => Input::get('password')
);
if(Auth::attempt($userdata))
{
// we are now logged in, go to admin
return Redirect::to('home');
}
else
{
return Redirect::to('login');
}
});
And form will change to:
{{ Form::open(array('url' => 'sign-in', 'class' => 'form-horizontal')) }}
P.S. You have a redirect loop, because, you have a two the same routes, and when you submit the form you redirect to login page again and again
If you are using Laravel 4.2 and still have issues after adding
{{ Form::token() }} or
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
Then you can try changing the filter.php file in app directory by adding
Request::getMethod() !== 'GET' on your filter.
Route::filter('csrf', function()
{
if (Request::getMethod() !== 'GET' && Session::token() != Input::get('_token'))
{
throw new Illuminate\Session\TokenMismatchException;
}
});
This has been useful to me too.

Categories