Validate/Authorize Current Password In Laravel 5.1 - php

I'm trying to add a password change feature for my logged in/authorized users. It's your plain ole generic set up:
Current Password
New Password
Confirm New Password
Obviously I can just use validate on the new password and password confirmation, but how do I authorize the current password submitted against their actual current password?
In the users model password is a hidden property so I can't just match them up.
I tried looking through Illiminate\Auth and Guard but I didn't see it anywhere. Perhaps I missed it, or maybe I'm going about this the wrong way?

Here's the answer in case anyone else is looking:
$validator = $this->validator($request->all());
$validator->after(function($validator) use ($request) {
$check = auth()->validate([
'email' => $this->user->email,
'password' => $request->current_password
]);
if (!$check):
$validator->errors()->add('current_password',
'Your current password is incorrect, please try again.');
endif;
});
if ($validator->fails()):
return redirect('account/password')
->withErrors($validator)
->withInput();
endif;
$this->user->password = bcrypt($request->password);
$this->user->save();

Get the current password and compare with the new password.
//use Auth, Hash, Input;
if (Hash::check(Input::get('new_password'), Auth::user()->password))
echo "Matched";
else
echo "Not matched";
Did you use the the laravel built in authentication package? If yes, the validation has been done for you. Check app/Http/Controller/Auth/AuthController.php, you can see this validation function. You can add more if you wish!:
protected function validator(array $data)
{
return Validator::make($data, [
'first_name' => 'required|max:255',
'last_name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
If any error happens during the above validation, it will be sent to the $errors variable where your blade view can catch them. So, in your reset password view (view/auth/reset.blade.php), you can catch the validation errors as follow:
#if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong> There were some problems with your input.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif

Related

How To show Password Wrong error to Users

i have a problem in showing error for users this is my Auth Login Controller :
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* #var string
*/
protected $redirectTo = RouteServiceProvider::HOME;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function login(Request $request)
{
$input = $request->all();
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8',
]);
if(auth()->attempt(array('email' => $input['email'], 'password' => $input['password'])))
{
if (auth()->user()->type == 'admin') {
return redirect()->route('admin.home');
}else if (auth()->user()->type == 'manager') {
return redirect()->route('manager.home');
}else{
return redirect()->route('home');
}
}else{
return redirect()->route('login')
->with('error','Email-Address And Password Are Wrong.');
}
$messages = [
'email.required' => 'Email is required',
'email.email' => 'Invalid email format',
'password.required' => 'Password is required',
'password.min' => 'Password must be at least 8 characters',
];
}
}
This is the LoginController from the default app in laravel i don't know why the messages of password wrong can't be showed in screen when i type wrong pass
i want to show users error if they use wrong password and this is the github link :
https://github.com/ElGrandeAchraf/skipshiftProjectCode.git
And Thank you For your attention.
It appears that the error message is not being displayed because it is being set on the redirect rather than being passed back to the view. In the else block of the login method, try replacing
return redirect()->route('login')->with('error','Email-Address And Password Are Wrong.');
With
return back()->withInput()->withErrors(['email' => 'Email-Address And Password Are Wrong.']);
This will pass the error message back to the view so it can be displayed.
Also, you can use $messages validation rules to show custom error messages, and you should call it before validate function like this:
$messages = [
'email.required' => 'Email is required',
'email.email' => 'Invalid email format',
'password.required' => 'Password is required',
'password.min' => 'Password must be at least 8 characters',
];
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|min:8',
], $messages);
Please note that this is just one possible solution and that it may not be the only problem you're facing in your code. You should also check the routes, views, and other related files, and make sure that everything is set up correctly.
Not sure if I was looking at the right Blade file, but in your resources/views/login.blade.php file I haven't seen anywhere that you would actually have the code to show errors. The controller doesn't do that for you automatically.
I you are returning with('error') then you should show it in Blade, something like:
#if (session('error'))
<div class="error">{{ session('error') }}</div>
#endif

I want to show a specific message when the user fail to login for username and password separately in laravel 5

I am using laravel login api.
I want to show a message for users who fail to login whether it's the username that is not correct or the password the right way.
I looked at AuthenticatesUsers.php there is a method that is responsible for returning a failed login message called sendFailedLoginResponse I edited it so it can do what I want and that's my code.
protected function sendFailedLoginResponse(Request $request)
{
$inputemail = $request->input('email');
$user = User::where('email', $inputemail)->first();
if($user == '') {
throw ValidationException::withMessages([
$this->username() => [trans('auth.usernameWrong')],
]);
} else {
throw ValidationException::withMessages([
'password' => [trans('auth.passwordWrong')],
]);
}
}
I know that there is a better way than this becasue I doubly checked the username the first one was laravel check and the second is my query check.
I am new to laravel and I want to know how it can be done the right way.
Try this
protected function sendFailedLoginResponse(Request $request)
{
// Load user from database
$user = \App\User::where($this->username(), $request->{$this->username()})->first();
if(!Hash::check($request->password, $user->password) {
throw ValidationException::withMessages([
$this->username() => [trans('auth.passwordWrong')],
]);
} elseif($!user->exists){
throw ValidationException::withMessages([
'password' => [trans('auth.usernameWrong')],
]);
}
}
Use Hash::check() method to check the password
This should help
Go to vendor\laravel\ui\auth-backend\AuthenticatesUsers.php and edit the existing function sendFailedLoginResponse(Request $request)
protected function sendFailedLoginResponse(Request $request)
{
$user = User::where($this->username(), $request->{$this->username()})->first();
if($user && !Hash::check($request->password, $user->password) ){
throw ValidationException::withMessages([
'password' => [trans('auth.password')],
]);
}else{
throw ValidationException::withMessages([
$this->username() => [trans('auth.email')],
]);
}
}
Don't forget to include:
use App\Models\User;
use Illuminate\Support\Facades\Hash;
Make sure the above codes are placed inside the vendor\laravel\ui\auth-backend\AuthenticatesUsers.php
Now you can navigate to resources\lang\en\auth.php and include in the code below:
'email' => 'The provided email is incorrect.',
'password' => 'The provided password is incorrect.',
You can check the password with Hash::check() method:
$user = User::where('email', $request->email)->first();
if (is_null($user)) {
// There is no user
} elseif (!Hash::check($request->password, $user->password) {
// Password is wrong
}

Laravel 5.4 add a message to validator's errors

So I am receiving data from a form that should reset user passwords:
Old Password: |field|
New Password: |field|
Confirm Password: |field|
And i want to be able to display a message out for the user if his old password does not match what he entered in the first field. I don't want to make an entirely new validation method and just want to throw an error to the use when i make my own if(). So how do I achieve this using the $errors variable that is available in my blade views
So here is an example of my controllers method
public function update(Request $request){
$this->validate($request,[
'oldPassword' => 'required',
'password' => 'required|min:8|confirmed'
]);
$user = Auth::user();
if(password_verify($request->newPass,$user->password)){
$user = User::find($user->id);
$user->password = bcrypt($request->newPass);
$user->save();
}else{
//the code for adding a new key to $errors variable
return back(); Or return redirect('path');
}
}
So in the view I want to this
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
You can do this in your controller:
$validator = Validator::make($request->all(),[
'oldPassword' => 'required',
'password' => 'required|min:8|confirmed'
]);
And then before your return back();, add:
$validator->after(function($validator) {
$validator->errors()->add('tagName', 'Error message');
});
With your message.

Posting data from two different forms in laravel?

I have a log in and register form that I'd like to set up on the same page.
The log in form works just fine, with dummy data already inputted in to the database that i'm using.
The issue I'm having is that I'm getting a method calling error (assumedly because I have the same post function call to two different functions.
Currently in my routes.php file I have
// route to process the form
Route::post('/', array('uses' => 'HomeController#doLogin'));
Route::post('/', array('uses' => 'HomeController#doRegister'));
And my controller file looks like this (sorry it's a little long, I thought it'd be better to provide everything instead of assuming someone can understand my question from just my explanation alone)
public function doRegister() {
$v = User::validate(Input::all());
if ( $v->passes() ) {
User::create(array(
'name'=> Input::get('name'),
'email'=> Input::get('email'),
'password'=> Hash::make(Input::get('password')),
));
return 'Thanks for registering!';
} else {
return Redirect::to('/')->withErrors($v->getMessages());
}
}
public function doLogin()
{
// validate the info, create rules for the inputs
$rules = array(
'email' => 'required|email', // make sure the email is an actual email
'password' => 'required|alphaNum|min:3' // password can only be alphanumeric and has to be greater than 3 characters
);
// run the validation rules on the inputs from the form
$validator = Validator::make(Input::all(), $rules);
// if the validator fails, redirect back to the form
if ($validator->fails()) {
return Redirect::to('/')
->withErrors($validator) // send back all errors to the login form
->withInput(Input::except('password')); // send back the input (not the password) so that we can repopulate the form
} else {
// create our user data for the authentication
$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
// attempt to do the login
if (Auth::attempt($userdata)) {
// validation successful!
// redirect them to the secure section or whatever
// return Redirect::to('secure');
// for now we'll just echo success (even though echoing in a controller is bad)
echo 'SUCCESS!';
} else {
// validation not successful, send back to form
return Redirect::to('/');
}
}
}
As far as I'm aware this is because I'm not setting which function to use correctly for my registration form.
Hopefully I've done an ok job at explaining my issue, any solution please? (rather new to laravel)
One form would post to login and the other to register
Route::post('login', array('uses' => 'HomeController#doLogin'));
Route::post('register', array('uses' => 'HomeController#doRegister'));
And then you would open the form like:
{{ Form::open(array('url' => 'login')) }}
and
{{ Form::open(array('url' => 'register')) }}
Edit:
And the forms would just be placed inside your home view for example, and then you would just redirect from the login and register methods, and not show a view.

Laravel 4 Auth::attempt() always returns false

I'm trying the Laravel's Auth class but everytime i attempt to log in a user, the method returns false. Here's my code:
Routes.php
Route::get('new-user', function() {
return View::make('register');
});
Route::post('new-user', function() {
$name = Input::get('name');
$email = Input::get('email');
$password = Hash::make(Input::get('password'));
$user = new User;
$user->name = $name;
$user->email = $email;
$user->password = $password;
$user->save();
});
Route::get('login', function() {
return View::make('login');
});
Route::post('login', function() {
$user = array(
'email' => Input::get('email'),
'password' => Hash::make(Input::get('password'))
);
if (Auth::attempt($user)) {
//return Redirect::intended('dashboard');
return "ok.";
} else {
return "Wrong.";
}
});
views/login.blade.php
{{ Form::open(array('url' => 'login', 'method' => 'post')) }}
<h1>Login:</h1>
<p>
{{ Form::label('email', 'Email: ') }}
{{ Form::text('email') }}<br />
{{ Form::label('password', 'Password: ') }}
{{ Form::password('password') }}<br />
</p>
<p>
{{ Form::submit('Login') }}
</p>
{{ Form::close() }}
config/auth.php
return array(
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users',
'reminder' => array(
'email' => 'emails.auth.reminder', 'table' => 'password_reminders',
),
);
The database has the email & password fields, and the password field is varchar(60).
Whenever i send the login info to /login it returns me "Wrong."
I really can't see whats wrong here?
Your code is bugging out because you are passing the wrong variables to Auth::attempt(). That method requires an array with keys username, password and optionally remember. In that light, your above code should be:
Route::post('login', function()
{
$credentials = [
'username' => Input::get('email'),
'password' => Input::get('password')
];
dd(Auth::attempt($credentials));
});
Hope that helps.
Also I'll give you snippets of extra code to improve your work flow. Route to store new user:
Route::post('register', function()
{
$input = Input::only(['username', 'email', 'password']);
// validate data
Eloquent::unguard();
$user = User::create($input);
Auth::loginUsingId($user->id);
return Redirect::to('dashboard');
});
Then in your user model add the method
public function setPasswordAttribute()
{
$this->password = Hash::make($this->password);
}
This way the password will be automatically hashed every time it's set
Don't hash the password before attempt:
$user = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
if (Auth::attempt($user)) {
//return Redirect::intended('dashboard');
return "ok.";
} else {
return "Wrong.";
}
this will not work because auth::attempt converts password to hash using bcrypt, and looks for that hash in users table to match.
in short the password should be a hash stored in database table for auth::attempt to work.
that is why your if() condition failing.
you can use bcrypt(password) to store password as hash in database and then use auth::attempt
below is from laravel docs
https://laravel.com/docs/5.2/authentication#authenticating-users
The attempt method accepts an array of key / value pairs as its first
argument. The values in the array will be used to find the user in
your database table. So, in the example above, the user will be
retrieved by the value of the email column. If the user is found, the
hashed password stored in the database will be compared with the
hashed password value passed to the method via the array. If the two
hashed passwords match an authenticated session will be started for
the user.
The attempt method will return true if authentication was successful.
Otherwise, false will be returned.
You should implement UserInterface class provided by laravel within your model class:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface
{
And remember that it has 2 abstract methods that you should declare at your model. You can follow original User.php model
Check your password Length. It must be 60 or higher in database.

Categories