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.
Related
I want to be able to display error message if a certain query returns false when attempting to log in user.
for example, as in my case i want to show a message to a user that his account has been deactivated if the deactivated column is set to 'yes'
Here is my code login method, i tried adding a second error, but both error returns if login fails, regardless of the failed query
public function login(Request $request)
{
$message = array(
'required.email' => 'Email is required',
'required.password' => 'Password is required',
);
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8',
]);
$email = $request->email;
$pass = $request->password;
if (Auth::attempt([
'email' => $email,
'password' => $pass,
'verified' => 'yes'
], $request->get('remember'))) {
return redirect()->intended(route('user.account.index'));
} else {
return redirect()->back()->withErrors(
[
'email' => 'These credentials do not match our records or this user has been deactivated!.',
'verified' => 'This user account has been deactivated! Contact support!'
]
);
}
}
And here is my login view
<form action="{{ route('login') }}" method="post">
#csrf
<span>Login Your Account</span>
<br><br>
#if (Session::has('message'))
<small class="alert alert-success">{{ Session::get('message') }}</small>
<br><br>
#endif
#if (Session::has('status'))
<small class="alert alert-info" role="alert">
{{ Session::get('status') }}
</small>
<br><br>
#endif
#error('verified')
<small class="alert alert-danger" role="alert">
{{ $message }}
</small>
<br><br>
#enderror
<div class="form-group">
<input type="email" class="form-control" placeholder="Email Address" name="email">
#error('email')
<br>
<small class="alert alert-danger" role="alert">
{{ $message }}
</small>
#enderror
</div>
<div class="form-group">
<input type="password" class="form-control" placeholder="Password" name="password">
#error('password')
<br>
<small class="alert alert-danger" role="alert">
{{ $message }}
</small>
#enderror
</div>
<div class="text-right">
Forgot Password?
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="form-checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="custom-control-label" for="form-checkbox">{{ __('Remember Me') }}</label>
</div>
<button type="submit" class="btn btn-danger">Login to account</button>
</form>
I will suggest using session flash messages instead of redirect witherror method. It has the advantage of being able to run custom messages in multiple situations. You can implement it like this: https://www.itsolutionstuff.com/post/laravel-5-implement-flash-messages-with-exampleexample.html
I also recommend checking this out to figure out how to customize your messages based on conditions.
In Laravel, the best way to pass different types of flash messages in the session
I am using JS Validator to validate my form fields in Laravel
Following is my code in usercontroller for validation
class UserController extends Controller
{
protected $changepassValidationRules = [
'old_password' => 'required|pwdvalidation|min:6',
'password' => 'required|min:6|confirmed',
];
}
I am passing $changepassValidationRules to view page for checking.
Following is my code in view page
<div class="col-md-4 col-sm-6 col-xs-12">
<div class="card">
<form method="post" action="{{ url('user/changepassword') }}" name="useredit" id="changepass"
enctype="multipart/form-data" novalidate>
{{ csrf_field() }}
#if (session('message_changepass'))
<div class="alert alert-success">
{{ session('message_changepass') }}
</div>
#endif
<div class="card-header">
<h4 class="card-title">
Change Password
</h4>
</div>
<div class="card-content">
<div class="form-group {{ $errors->has('old_password') ? ' has-error' : '' }}">
<label class="control-label">Old Password
<star> *</star>
</label>
<input type="password" placeholder="Password" class="form-control" id="old_password"
name="old_password">
#if ($errors->has('old_password'))
<span class="help-block error-help-block">
{{ $errors->first('old_password') }}
</span>
#endif
</div>
<div class="form-group {{ $errors->has('password') ? ' has-error' : '' }}">
<label class="control-label">New Password
<star> *</star>
</label>
<input type="password" placeholder="Password" class="form-control" id="password" name="password">
#if ($errors->has('password'))
<span class="help-block">
{{ $errors->first('password') }}
</span>
#endif
</div>
<div class="form-group">
<label class="control-label">Confirm Password
<star> *</star>
</label>
<input id="password-confirm" type="password" class="form-control" name="password_confirmation"
placeholder="Confirm Password">
</div>
<div class="form-action">
<button type="submit" class="btn btn-fill btn-info">Submit</button>
</div>
</div>
</form>
</div>
All other validations rules are working perfectly, but issue is that I want to validate current password already in DB.
if user enters a wrong password error should be thrown, what is the problem here
You can use Custome Validate Rule to create your own custome validate
1.I will create MatchCurrentPassword Rule
php artisan make:rule MatchCurrentPassword
2.In rule code
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\Hash;
class MatchCurrentPassword implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return Hash::check($value, auth()->user()->password);
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return ':attribute is not match';
}
}
in your UserController
use App\Rules\MatchCurrentPassword;
class UserController extends Controller
{
public function changePassword(Request $request) {
$request->validate([
'old_password' => ['required', 'min:6', new MatchCurrentPassword],
'password' => 'required|min:6|confirmed',
]);
// you logic code
}
}
you can move request to form request also Form Request Validation
Hope it help
You can trigger ajax request on current password's blur and write code in controller to match the current password that the use has entered is correct or not if not then return false and it will come in error's callback function from where you can show the error .
$("$crntPwd").on("blur",function(){
$.ajax({
url:'your url',
method: 'get/post',
data : {current pwd's value},
success:function(response){
console.log(response);
},
error:function(error){
console.log(error or "your current password is incorrect");
}
});
});
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.');
}
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()
I wrote a laravel form, its screen shot is as given below:
And I use neo4j for storing that form data.
Here is the code:
app/views/duck-form.blade.php
<!doctype html>
<html>
<head>
<title>Laravel Form Validation!</title>
<!-- load bootstrap -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<style>
body { padding-bottom:40px; padding-top:40px; }
</style>
</head>
<body class="container">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div class="page-header">
<h1><span class="glyphicon glyphicon-flash"></span> Register! </h1>
</div>
#if ($errors->has())
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
{{ $error }}<br>
#endforeach
</div>
#endif
<!-- FORM STARTS HERE -->
<form method="POST" action="/ducks" novalidate>
<div class="form-group #if ($errors->has('name')) has-error #endif">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" placeholder="Enter your name" value="{{ Input::old('name') }}">
#if ($errors->has('name')) <p class="help-block">{{ $errors->first('name') }}</p> #endif
</div>
<div class="form-group #if ($errors->has('email')) has-error #endif">
<label for="email">Email</label>
<input type="text" id="email" class="form-control" name="email" placeholder="Enter your email id" value="{{ Input::old('email') }}">
#if ($errors->has('email')) <p class="help-block">{{ $errors->first('email') }}</p> #endif
</div>
<div class="form-group #if ($errors->has('password')) has-error #endif">
<label for="password">Password</label>
<input type="password" id="password" class="form-control" name="password">
#if ($errors->has('password')) <p class="help-block">{{ $errors->first('password') }}</p> #endif
</div>
<div class="form-group #if ($errors->has('password_confirm')) has-error #endif">
<label for="password_confirm">Confirm Password</label>
<input type="password" id="password_confirm" class="form-control" name="password_confirm">
#if ($errors->has('password_confirm')) <p class="help-block">{{ $errors->first('password_confirm') }}</p> #endif
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
</div>
</body>
</html>
1. I added 'Artdarek\Neo4j\Neo4jServiceProvider' to providers array in app/config/app.php.
2. I added neo4j configuration in app/config/database.php
'neo4j' => [
'default' => [
'host' => 'localhost',
'port' => 7474,
'username' => null,
'password' => null,
],
],
3. Then I added a controller for that form:
<?php
class DuckController extends BaseController {
public function showWelcome()
{
return View::make('duck');
}
}
4. This is my routes.php.
<?php
Route::get('/', function()
{
return View::make('hello');
});
// route to show the duck form
Route::get('ducks', function()
{
return View::make('duck-form');
});
// route to process the ducks form
Route::post('ducks', array('before' => 'csrf', function()
{
// create the validation rules ------------------------
$rules = array(
'name' => 'required', // just a normal required validation
'email' => 'required|email|unique:ducks', // required and must be unique in the ducks table
'password' => 'required',
'password_confirm' => 'required|same:password' // required and has to match the password field
);
// create custom validation messages ------------------
$messages = array(
'required' => 'The :attribute is really really really important.',
'same' => 'The :others must match.'
);
// do the validation ----------------------------------
// validate against the inputs from our form
$validator = Validator::make(Input::all(), $rules, $messages);
// check if the validator failed -----------------------
if ($validator->fails()) {
// redirect our user back with error messages
$messages = $validator->messages();
// also redirect them back with old inputs so they dont have to fill out the form again
// but we wont redirect them with the password they entered
return Redirect::to('ducks')
->withErrors($validator)
->withInput(Input::except('password', 'password_confirm'));
} else {
// validation successful ---------------------------
// our duck has passed all tests!
// let him enter the database
// create the data for our duck
$duck = new Duck;
$duck->name = Input::get('name');
$duck->email = Input::get('email');
$duck->password = Hash::make(Input::get('password'));
// save our duck
$duck->save();
// redirect ----------------------------------------
// redirect our user back to the form so they can do it all over again
return Redirect::to('ducks')
->with('messages', 'Hooray!');
}
}));
5. This is my model file for form:
<?php
class Duck extends Eloquent {
protected $fillable = array('name', 'email', 'password');
}
6. This is my model for neo4j:
<?php
//use Illuminate\Auth\EloquentUserProvider;
class database extends Eloquent {
public function index($name, $email, $password, $password_confirm) {
$formData = Neo4j::makeNode();
$formData->setProperty('name',$name)
->setProperty('email',$email)
->setProperty('password',$password)
->setProprty('password_confirm',$password_confirm)
->save();
}
}
When I click on that submit button in that form, I get this error:
[ Edit ]
I was working on it:
This is the new error which I got:
Is it a csrf token issue?
It is pointing to:
Route::filter('csrf', function()
{
if (Session::token() != Input::get('_token'))
{
throw new Illuminate\Session\TokenMismatchException;
}
});
I'm unable to resolve it since 5 hours and data isn't getting stored in neo4j DB. How can I fix it?
When using the CSRF Protection Filter, your form must be declared in your blade as such:
{{ Form::open(array('method' => 'POST', 'action' => URL::to("/ducks"))) }}
And closed:
{{ Form::close() }}
This will render the same form in your html as using:
<form method="POST" action="{{ URL::to("/ducks") }}">...</form>
But will also add the hidden _token element that you are missing:
<input type="hidden" name="_token" value="value_of_token"/>
Hope that helps!
Edit
Or, if you don't want to recreate your <form>, you may simply use:
{{ Form::token() }}
Somewhere inside your existing <form> tag to create it.
Your code looks fine, might be you need to run
composer dump-autoload