I need to check the password given by the user in an input and check it. If it's right I'll update the password with new password, if the password is wrong I want to give the user an alert in laravel 5.4.
controller:
public function edit(Request $request){
$user = new User;
$user = $user->find(1);
$oldpassword = $request->input('oldpassword');
$newpassword = $request->input('newpassword');
//if condition
/*if (user()->id == $oldpassword){
$updatesucess = 1;
}else {
$updatesucess = 0;
}*/
$user->update(['password' => $newpassword]);
return back();
}
view:
#section('content')
<div class="form">
<div class="logo-area">
<img src="images/logo.png">
</div>
<form method="POST" action="/edit">
{{ csrf_field() }}
<input type="password" name="oldpassword" placeholder="old Password" required>
<input type="password" name="newpassword" placeholder="new Password" required>
<input type="submit" value="Save changes">
</form>
Use check method of Hash facade (documentation)
In your controller file add Hash facade:
use Illuminate\Support\Facades\Hash;
Add password check and in case of mismatch handle redirect with an error
$user = User::find(1);
$oldpassword = $request->input('oldpassword');
if (Hash::check($oldpassword, $user->password)) {
// redirect back with error
}
Update user password using Hash::make
$newpassword = $request->input('newpassword');
$user->update(['password' => Hash::make($newpassword)]);
For Laravel versions>8 this is the best solution.
'old_password' => 'required|current_password'
You can also specify the api
'old_password' => 'required|current_password:web'
Related
I am using laravel 6. I am trying to implement forgot password for my laravel project for the first time. I have customize the default design for login, forgot password, reset password pages. I have integrated mailtrap for sending email. I have successfully implemented flow like -
click forgot password link
get page on which user enters email and click to send reset link
gets the email of resetting link and data like email, token , created_at stores in password_reset table
on click of reset link page with token and email url gets open in new tab(open the page of reset password having email, new password, confirm password)
Further when I type new password and confirm password and click on Reset Password, nothing happens.
my reset.blade.php
<form id="sign_in" name="sign_in" method="POST" action="{{ route('password.update') }}" data-parsley-validate >
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<h1>Reset Password</h1>
<div class="col-md-12 col-sm-12 form-group has-feedback">
{{-- <label for="login_id"><span style="color:red;">*</span>Login ID</label> --}}
<input id="email" type="email" class="form-control has-feedback-left #error('email') is-invalid #enderror" placeholder="Email" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus/>
<span class="fa fa-envelope form-control-feedback left" aria-hidden="true"></span>
#error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
<div class="col-md-12 col-sm-12 form-group has-feedback">
<input id="password" type="password" class="form-control has-feedback-left #error('password') is-invalid #enderror" placeholder="Password" name="password" required autocomplete="new-password" />
<span class="fa fa-pencil form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-12 col-sm-12 form-group has-feedback">
<input id="password-confirm" type="password" class="form-control has-feedback-left" placeholder="Confirm Password" name="password_confirmation" required autocomplete="new-password" />
<span class="fa fa-pencil form-control-feedback left" aria-hidden="true"></span>
</div>
<button type="submit" class="btn btn-success">Reset Password</button>
</div>
<div class="clearfix"></div>
</form>
I have default controllers generated for auth like 'ConfirmPasswordController, ForgotPasswordController, ResetPasswordController, VerificationController'
ResetPasswordController
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* #var string
*/
protected $redirectTo = '/dashboard';
}
I have used default route of auth like Auth::routes();
how the passwords reset in database in users table for email and token generated in password_reset table and how the message gets displayed that 'Password reset successfully? This is not working in my case.userstable not changing with new password and entry not gets removed frompassword_reset` table once the reset done successfully.
where and what changes I have to make to make this work? please guide. thanks in advance.
Password Reset in Laravel
Step 1 — Create a Route and a Controller
Create two routes, a controller, and methods through which the email address that requires a password reset will be submitted via the password reset form. The name of these routes, controllers, and methods is totally up to you.
Route::post('reset_password_without_token', 'AccountsController#validatePasswordRequest');
Route::post('reset_password_with_token', 'AccountsController#resetPassword');
Step 2— Change the action property on the default password reset form
<form method="POST" action="{{ url('/reset_password_without_token') }}">
The default password reset form can be found here:
resources/views/auth/passwords/email.blade.php
Step 3 — Create a token and Send Password Reset Link via email
Then add the validatePasswordRequest method in the AccountsController and use or modify the code below.
//You can add validation login here
$user = DB::table('users')->where('email', '=', $request->email)
->first();
//Check if the user exists
if (count($user) < 1) {
return redirect()->back()->withErrors(['email' => trans('User does not exist')]);
}
//Create Password Reset Token
DB::table('password_resets')->insert([
'email' => $request->email,
'token' => str_random(60),
'created_at' => Carbon::now()
]);
//Get the token just created above
$tokenData = DB::table('password_resets')
->where('email', $request->email)->first();
if ($this->sendResetEmail($request->email, $tokenData->token)) {
return redirect()->back()->with('status', trans('A reset link has been sent to your email address.'));
} else {
return redirect()->back()->withErrors(['error' => trans('A Network Error occurred. Please try again.')]);
}
The sendResetEmail method is a private method that sends an email with the reset link to the user. Here you can use whatever email app you choose to use. Maybe, you have a custom email service for your organization, you can use it here, not relying on the options Laravel has by default.
private function sendResetEmail($email, $token)
{
//Retrieve the user from the database
$user = DB::table('users')->where('email', $email)->select('firstname', 'email')->first();
//Generate, the password reset link. The token generated is embedded in the link
$link = config('base_url') . 'password/reset/' . $token . '?email=' . urlencode($user->email);
try {
//Here send the link with CURL with an external email API
return true;
} catch (\Exception $e) {
return false;
}
}
The link generated and sent to the user when clicked will direct the user to your domain.com/password/reset/token?email=’user#email.com’. You can find the view here: resources/views/auth/passwords/reset.blade.php
Step 4 - Reset the User's password
Add this method to the AccountsController. Go through the comments, they explain each step.
public function resetPassword(Request $request)
{
//Validate input
$validator = Validator::make($request->all(), [
'email' => 'required|email|exists:users,email',
'password' => 'required|confirmed'
'token' => 'required' ]);
//check if payload is valid before moving on
if ($validator->fails()) {
return redirect()->back()->withErrors(['email' => 'Please complete the form']);
}
$password = $request->password;
// Validate the token
$tokenData = DB::table('password_resets')
->where('token', $request->token)->first();
// Redirect the user back to the password reset request form if the token is invalid
if (!$tokenData) return view('auth.passwords.email');
$user = User::where('email', $tokenData->email)->first();
// Redirect the user back if the email is invalid
if (!$user) return redirect()->back()->withErrors(['email' => 'Email not found']);
//Hash and update the new password
$user->password = \Hash::make($password);
$user->update(); //or $user->save();
//login the user immediately they change password successfully
Auth::login($user);
//Delete the token
DB::table('password_resets')->where('email', $user->email)
->delete();
//Send Email Reset Success Email
if ($this->sendSuccessEmail($tokenData->email)) {
return view('index');
} else {
return redirect()->back()->withErrors(['email' => trans('A Network Error occurred. Please try again.')]);
}
}
There you have it. This should be enough to get things working.
I had the same problem, I was able to solve it this way,
first i add a route:
Route::get('password/reset/{token}', [App\Http\Controllers\Auth\ResetPasswordController::class, 'showResetForm'])->name('password.reset');
next i add in reset.blade.php
<input type="hidden" name="token" value="{{$token}}">
that's it, it works for me. Maybe someone will also need it
I've made a login function in which I render a template after checking the login and password. This's the form that i've made inside a template.
<form action="{{ path("login") }}" method="post" id="formulaire_connexion">
<label class="control-label">Email
<input type="text" name="email" id="email" placeholder="your#email.com" onclick="this.select()"/>
</label>
<label class="control-label">Password</br>
<input type="password" name="password" id="password" placeholder="*********" onclick="this.select()"/>
</label>
<input type="checkbox" id="remember_me" name="remember_me"><label for="remember_me">Remember me </label></br>
<button type="submit" id="connexion" name="connexion">Connexion</button>
</form>
And this's the logging check method :
public function loginAction(Request $request)
{
$mail = $request->get('email');
$pass = $request->get('password');
$oauth = new OAuth($mail, $pass);
$baseUrl = "http://api.localhost/v1/";
$connexion = "{$baseUrl}login/".$mail."/".$pass;
$oauth->fetch($connexion, $_REQUEST, OAUTH_HTTP_METHOD_GET);
$reponseInformations = json_decode($oauth->getLastResponse(), true);
if (!$reponseInformations) {
$data['erreur'] = "Bad credentials";
return $this->render('EspacePointDeVenteBundle:Authentication:authentication.html.twig', array(
'erreur' => $data,
));
}else{
return $this->render('EspacePointDeVenteBundle:Home:index.html.twig', array(
'reseau' => $reseau,
'identifiant' => $key,
'key' => $identifiant,
));
}
}
After a wrong login connexion I render the same login template, but the routing is changed to /login instead of havig /index per example. What I need to know how to keep the same routing even if we called a foreign method.
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.
I am trying to create a reset option in my project. If user is doing their first login, it will redirect to reset page.
This is the view part
<div class="form-group{{ ($errors->has('cpassword')) ? 'has error' : '' }}">
<label for="cpassword">Current Password: </label>
<input id="cpassword" name="cpassword" type="text" class="form-control">
#if($errors->has('cpassword'))
{{ $errors->first('cpassword')}}
#endif
</div>
<div class="form-group{{ ($errors->has('password')) ? 'has error' : '' }}">
<label for="password">New Password: </label>
<input id="password" name="password" type="password" class="form-control">
#if($errors->has('password'))
{{ $errors->first('password')}}
#endif
</div>
<div class="form-group{{ ($errors->has('password2')) ? 'has error' : '' }}">
<label for="password2">Confirm Password: </label>
<input id="password2" name="password2" type="password" class="form-control">
#if($errors->has('password2'))
{{ $errors->first('password2')}}
#endif
</div>
{{ Form::token() }}
<div class="form-group">
<input type="submit" value="Submit" class="btn btn-default">
</div>
in reset page we need to enter old password, new password and confirm password..
Controller part is given below
public function postReset(){
$validator =Validator::make(Input::all(), array(
'cpassword' => 'required',
'password' => 'required|min:8',
'password2' => 'required|min:8|same:password'
));
if ($validator->fails())
{
return Redirect::route('resetPassword')->withErrors($validator)->withInput();
}
else
{
if (Auth::attempt(array('username'=>Auth::user()->username, 'password'=>Hash::make(Input::get('cpassword'))))) {
return 'password is resetted';
}
}
}
But if I tried to verify current password and userpasssword, their hash codes doesn't match. Is there any other methods to reset passord. I need the same view part.
Can anyone help??
The Auth::attempt() method needs the plain password you must not generate a hash yourself. Also Laravel's hashes can't be validated just by comparing them because every hash contains a random salt. To compare a password with it's hash you have to use Hash::check(). Also, while Auth::attempt() works Auth::validate() would be the better choice since your user is already logged in:
$credentials = array(
'username' => Auth::user()->username,
'password' => Input::get('cpassword')
);
if(Auth::validate($credentials)){
return 'password is resetted';
}
Laravel has a "forgot" password feature built in which you can use to let people reset passwords if they have forgot them.
You can find that at: http://laravel.com/docs/5.0/authentication
If you want someone to be able to change their password (and they are able to remember the old one), you can do something like this:
if(Input::get('passwordIs')) {
if (!Hash::check(Input::get('passwordIs'), Auth::user()->password))
return Redirect::to('my-account/settings/')->withErrors(Lang::get('account.password-wrong'));
else {
if(Input::get('passwordIsNew') !== Input::get('passwordIs_confirmation'))
return Redirect::to('my-account/settings/')->withErrors(Lang::get('account.passwords-must-match'));
else{
$password = Hash::make(Input::get('passwordIs_confirmation'));
$customer = Auth::user();
$customer->password = $password;
$customer->save();
}
}
}
I am trying to get the login to work in Kohana, but so far it fails to log the user in.
I have been successfully able to create new users, so I have all the tables set up.
My view for the login page is as follows,
<td style="vertical-align:top">
<div id="log_in">
<form class="pure-form pure-form-stacked" action="/kohana-blog/index.php/signup/login" method="post">
<fieldset>
<legend>Log In</legend>
<label for="username">Username</label>
<input id="username" name="username" type="text" placeholder="nonamedude" required>
<label for="password">Password</label>
<input id="password" name="password" type="password" placeholder="Password" required>
<label for="remember" class="pure-checkbox"></label>
<input id="remember" type="checkbox"> Remember me
<br>
<button type="submit" class="pure-button notice">Log In</button>
</fieldset>
</form>
</div>
</td>
My controller is as follows
$this->template->content = View::factory('signup/home')
->bind('message', $message);
if (HTTP_Request::POST == $this->request->method())
{
$remember = array_key_exists('remember', $this->request->post()) ? (bool) $this->request->post('remember') : FALSE;
$remember = FALSE;
$user = Auth::instance()->login($this->request->post('username'), $this->request->post('password'), $remember);
if ($user)
{
Request::current()->redirect('signup/home');
}
else
{
$message = "login failed";
}
}
I can't figure out why it doesn't authenticate the user.
My auth.php is as follows:
'driver' => 'orm',
'hash_method' => 'sha256',
'hash_key' => 'somerandomstring',
'lifetime' => 1209600,
'session_type' => Session::$default,
'session_key' => 'auth_user',
Additionally, the roles_users table have the correct values and the users table has the data from the form.
Is there a way to debug this to find the source of the issue?
First of all make sure your user has login role assigned in roles_users table.
By default you won't be able to login if you don't have this role.
Btw. it's cleaner to write:
$post = $this->request->post();
$user = Auth::instance()->login($post['email'], $post['password'], isset($post, 'remember'));