How to change password in laravel-4 with auth - laravel-4

I am using laravel-4 auth component . I want to make a function which will change user password . I have my view as follows :
password - Text-box ;
new_password - Text-box;
confirm_new_password - Text-box
I also have checked manual for password reset , but in that doc(http://laravel.com/docs/security#password-reminders-and-reset) they are sending mail for password reset .
View is as follows :
#extends('layouts.main')
#section('title') Change Password
#stop
#section('content')
{{ Form::open(array('url'=>'users/user-password-change', 'class'=>'block small center login')) }}
<h3 class="">Change Password</h3>
<h6>Please change your password below.</h6>
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
{{ Form::password('password', array('class'=>'input-block-level', 'placeholder'=>'Old Password')) }}
{{ Form::password('new_password', array('class'=>'input-block-level', 'placeholder'=>'New Password')) }}
{{ Form::password('confirm_new_password', array('class'=>'input-block-level', 'placeholder'=>'Confirm New Password')) }}
{{ Form::submit('Register', array('class'=>'k-button'))}}
{{ Form::close() }}
#stop
Controller code is as follows :
public function postUserPasswordChange(){
$validator = Validator::make(Input::all(), User::$change_password_rules);
if($validator->passes()){
$user=new UserEventbot;
$user->password=Hash::make(Input::get('new_password'));
$user->save();
return Redirect::to('users/change-password');
}else {
return Redirect::to('users/change-password')->with('message', 'The following errors occurred')->withErrors($validator)->withInput();
}
}
Please help me on this , how to first match this password with database table users , and then the whole process .
Thank you .

To match current user password with password in database you can do something like this,
// retrieve the authenticated user
$user = Auth::user();
Retrieve the current password specified by the user inside the form,
$current_password = Input::get('current_password');
We can see if the current password has bee specified and check against the hashed password as follows,
if (strlen($current_password) > 0 && !Hash::check($current_password, $user->password)) {
return Redirect::to('/user/edit-profile')->withErrors('Please specify the good current password');
}
Important thing to note here is the function
Hash::check(CURRENT_PASSWORD_ENTERED_IN_FORM, HASHED_VERSION_OF_PASSWORD_STORED_IN_AUTH_USER)
Finally, if it's all good you can update the current user password inside Auth and in database as follows,
// authenticated user
$user = Auth::user();
$user->password = Hash::make($new_password);
// finally we save the authenticated user
$user->save();

Try the following:
public function postUserPasswordChange(){
$validator = Validator::make(Input::all(), User::$change_password_rules);
if($validator->passes()){
$user = UserEventbot::findOrFail(Auth::user()->id);
$user->password = Hash::make(Input::get('new_password'));
$user->save();
return Redirect::to('users/change-password');
}else {
return Redirect::to('users/change-password')->with('message', 'The following errors occurred')->withErrors($validator)->withInput();
}
}

this is my own solution, I have 3 inputs = old_password, password, password_confirmation, form with action=post.
Validator check requirements, hash checks if Old password matches
public function changePassword()
{
$user = Auth::user();
$rules = array(
'old_password' => 'required|alphaNum|between:6,16',
'password' => 'required|alphaNum|between:6,16|confirmed'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails())
{
return Redirect::action('UserController#show',$user->id)->withErrors($validator);
}
else
{
if (!Hash::check(Input::get('old_password'), $user->password))
{
return Redirect::action('UserController#show',$user->id)->withErrors('Your old password does not match');
}
else
{
$user->password = Hash::make(Input::get('password'));
$user->save();
return Redirect::action('UserController#show',$user->id)->withMessage("Password have been changed");
}
}
}

Please try the following changed
public function postUserPasswordChange(){
$validator = Validator::make(Input::all(), User::$change_password_rules);
if($validator->passes()){
$user = UserEventbot::findOrFail(Auth::user()->id);
if(Hash::check(Input::get('password'), $user->getAuthPassword())) {
$user->password = Hash::make(Input::get('new_password'));
$user->save();
return Redirect::to('users/change-password')->with('message','Your password has been changed');
}
}
return Redirect::to('users/change-password')->with('message', 'The following errors occurred')->withErrors($validator);
}
You should exclude withInput() in term of password.Hope this help

Related

Status Message After Password Reset

All this code works just fine except when the password is updated. I am not getting the status message that password is updated once Auth::logout() is fired and returned to the login screen. It does change the password but no message. If there is an error, it returns back and displays a sweetalert message that passwords do not match.
Controller
public function UserUpdatePassword(Request $request)
{
$validateData = $request->validate([
'oldpassword' => 'required',
'password' => 'required|confirmed',
]);
$hashedPassword = Auth::user()->password;
if(Hash::check($request->oldpassword,$hashedPassword)){
$user = User::find(Auth::id());
$user->password = Hash::make($request->password);
$user->save();
Auth::logout();
return redirect()->route('user.logout')->with('status','Password Updated Successfully');
} else{
Alert::warning('Password Mismatch','Current Password Error or Password Confirm Do Not Match');
return redirect()->back();
}
}
on login screen
#if (session('status'))
<div class="alert" role="alert" style="background-color:#C5ECEB;">
{{ session('status') }}
</div>
#endif
Your
Auth::logout();
is before showing the status;
So If you want to show the status message, just comment logout line as follows:
$user = User::find(Auth::id());
$user->password = Hash::make($request->password);
$user->save();
return redirect()->route('user.logout')->with('status','Password Updated Successfully');
Put \Session::put('status','Password Updated Successfully');
before Auth::logout();

How To Display Laravel Breeze Status Message

I'm using Laravel Breeze for authentication, and I'm facing a problem:
When user request a password reset link, I like to show him/her a success message, if we send email successfully. PasswordResetLinkController returns this:
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
When it goes back, it goes, for example, to home route. HomeController returns home.blade.php. When I try to display $status, which should be passed by PasswordResetLinkController, I got undefiened variable error. How can I get that message?
EDIT
PasswordResetLinkController.php
// This is the original store function came with Breeze.
// I did touch neither code nor the comments.
public function store(Request $request)
{
$request->validate([
'email' => 'required|email',
]);
// We will send the password reset link to this user. Once we have attempted
// to send the link, we will examine the response then see the message we
// need to show to the user. Finally, we'll send out a proper response.
$status = Password::sendResetLink(
$request->only('email')
);
return $status == Password::RESET_LINK_SENT
? back()->with('status', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
HomeController.php
public function index()
{
$baseData = $this->baseData();
$asset = $this->pickAssetRandom();
$publishings = $this->paginate($this->getPublishings, 12);
return view('pages.home', compact('publishings', 'baseData', 'asset'));
}
The $status is being set in the PasswordResetLinkController.
Specifically:
back()->with('status', __($status))
So, as you can see, it is returning the previous page and passing in status.
However, if $status == Password::RESET_LINK_SENT is false, then $status is not set, but the $errors['email'] is. You can see this on the ternary condition in your code.
Try:
dd($status == Password::REST_LINK_SENT);
before the return statement on the controller, if you get false then there will be no $status, and you will get the undefiened variable error.
You can account for this in your view:
#if ($status)
{{ $status }} // A link was sent
#endif
// no link sent and here are the errors.
#if ($errors->any())
#foreach ($errors->all() as $error)
{{ $error }}
#endforeach
#endif
Laravel docs on this: https://laravel.com/docs/8.x/passwords#resetting-the-password
Treat that status as a session and it will work
#if (session('status'))
<span class="alert alert-success">{{ session('status') ?? ''}} </span>
#endif

Only email and password for login

I have many attributes for the users' table. Admin needs to register a new user. My question is how to log in only with email and password?. my code now when user login user will get this error and this users database table . I only want to insert email and password when login in.
Controller\Auth\AuthController.php
public function login(Request $request)
{
if (!\Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
return redirect()->back();
} else {
return view('layouts.admin');
}
}
Http\UserController.php
public function store(Request $request)
{
$user = new User();
$user->Id_staff = $request['Id_staff'];
$user->name = $request['name'];
$user->noIc = $request['noIc'];
$user->email = $request['email'];
$user->password = bcrypt($request['password']);
$user->pusat_tangungjawab = $request['pusat_tangungjawab'];
$user->jawatan = $request['jawatan'];
$user->user_group = $request['user_group'];
$user->user_level = $request['user_level'];
$user->phone_no = $request['phone_no'];
$user->save();
return redirect()->route('users.index');
}
If you create a migration for users table, maybe the reason for that error because you didn't set nullable for Id_staff. So if you create a user and didn't post a value of Id_staff you will get that error. Some solutions is set a default value by random or set nullable in your migration, for example:
$table->string('Id_staff')->nullable();

How To Get Auth ID form user table and grab it for store to other table on database

I want to get Auth ID from user who has logged in and then use the Auth ID to store on other table
User_detail Controller
this is my store function
$data = new ModelUser();
$user= new user();
$data->fill(Auth::user());
$data->id_user = Auth::get('id');
$data->jenis_kelamin = $request->jenis_kelamin;
$data->no_tlp = $request->no_tlp;
$data->jurusan = $request->jurusan;
$data->wilayah = $request->wilayah;
$data->save();
return redirect()->route('surveylist');
and this is function Login
public function LoginPost(Request $request)
{
$email = $request->email;
$password = $request->password;
$data = user::where('email',$email)->first();
if($data) //check email apakah ada atau tidak
{
if(Hash::check($password,$data->password))
{
Session::put('id',$data->id);
Session::put('full_name',$data->full_name);
Session::put('email',$data->email);
Session::put('login',TRUE);
return redirect('userdt');
}
else
{
return redirect('index')->with('alert','Password atau Email yang anda masukan salah !!! ' );
}
}
}
this is the routes files
Route::get('/index','UserController#show')->name('surevey.index');
Route::get('/logout','UserController#Logout')->name('user.logout');
Route::post('/registerpost','UserController#RegisterPost')->name('user.register');
Route::post('/loginpost','UserController#LoginPost')->name('user.login');
//reward routes
Route::get('/reward','RewardController#index')->name('reward.list');
//profile
Route::put('/editprofile/edit/{id}','UserController#edit')->name('profile.edit');
Route::post('/editprofile/update','UserController#update')->name('profile.update');
Route::get('/userdt',['middleware'=>'auth','uses'=>'UserController#userdetail'])->name('userdt.show');
Route::post('/userdt/store','UserController#store')->name('userdt.store');
//Survei
Route::get('/createsurvey','SurveyController#show')->name('survey.create');
Route::get('/surveylist','SurveyController#index')->name('survey.list');
Auth::routes();
ModelUser
protected $fillable = [
'id_user',
'jenis_kelamin',
'no_tlp',
'jurusan',
'wilayah'
];
protected $table ='user_detail';
public function user()
{
return $this->belongsTo(user::class);
}
and I get error like this
Argument 1 passed to Illuminate\Database\Eloquent\Model::fill() must
be of the type array, null given, called in
E:\Laravel\surevey\app\Http\Controllers\UserController.php on line 110
You don't need to use $data->fill(Auth::user()); as you have only single user_id field need to set.
Also you can get the current logged in user's id using. \Auth::user()->id
So your code would be as follow:
$data = new ModelUser();
$data->id_user = \Auth::user()->id;
$data->jenis_kelamin = $request->jenis_kelamin;
$data->no_tlp = $request->no_tlp;
$data->jurusan = $request->jurusan;
$data->wilayah = $request->wilayah;
$data->save();
return redirect()->route('surveylist');
Note: Make sure you have included auth middleware with your route.
Like:
Route::get('profile', ['middleware' => 'auth', function() {
// Only authenticated users may enter...
}]);
And you have followed the authuntication process carefully.
https://laravel.com/docs/5.2/authentication
Edited:
Your loging should be changed as:
public function LoginPost(Request $request)
{
$email = $request->email;
$password = $request->password;
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect()->intended('userdt');
}
return redirect('index')->with('alert','Password atau Email yang anda masukan salah !!! ' );
}
If your reverse one-to-one relationship in the User Model looks like this:
public function detail()
{
return $this->hasOne(ModelUser::class);
}
And you are sure a user is logged in, you could simply do this
$data = Auth::user()->detail()->save($request->all());
return redirect()->route('surveylist');
Laravel's ORM takes care of the rest.
should be Auth::id() or Auth::user()->id but seems like your Auth::user() is returning a null.make sure you sessions, routes are set up properly.
use Auth::attempt()to login user

How to get a custom message on fail login credentials in Laravel?

I use this code to check user credentials, but I can't figure how to change the code to get an error message when credentials fail. Used redirect and so on, but show nothing....
public function loginWithCredentials(Request $request) {
$signinEmail = $request->input('email');
$signinPassword = $request->input('password');
$user = new Users();
$errors = new MessageBag;
$user = $user
->where('email', '=', $signinEmail)
->get()->first();
if(empty($user)) {
$errors->add('error', 'Invalid credentials!');
return json_encode([
'error'=>true,
'messages'=>$errors
]);
}
$userdata = $user->toArray();
if(md5($signinPassword) != $userdata['password']) {
$errors->add('error', 'Invalid credentials!');
return redirect()->guest('auth/login');
}
Session::put('user',$userdata);
$errors->add('message0', 'Welcome ' . strtoupper($userdata['username']) . '!');
}
Now it just simple redirects me to a white page with the "invalid credentials" message. I want the message to be on login page.
Your code you has some flaws, consider fixing it.
Why are you mixing json response with html response?
Consider using bcrypt() for hashing your users passwords instead md5().
Add some sort of validation, Laravel has the built in validation.
Laravel ships with easy use login auth, take a look at.
So in your code needs some changes here it is:
public function loginWithCredentials(Request $request) {
$signinEmail = $request->input('email');
$signinPassword = $request->input('password');
$user = new Users();
$user = $user
->where('email', '=', $signinEmail)
->get()->first();
if(empty($user) || md5($signinPassword) != $user->password) {
return redirect()->back()->with('message', 'Invalid credentials!');
}
$userdata = $user->toArray();
Session::put('user', $userdata);
return view('view.name')->with('message', 'Welcome ' . strtoupper($userdata['username']) . '!');
}
Then in your view you write the success message like so:
#if (session('message'))
<div class="alert alert-success">
{{ session('message') }}
</div>
#endif
this example is using blade, but should be similar to other views.
You just need to override AuthenticatesUsers Trait method named sendFailedLoginResponse like this:
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Validation\ValidationException;
use Illuminate\Http\Request;
class LoginController extends Controller
{
use AuthenticatesUsers;
...
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
'your array key' => ['Place your custom message here'],
]);
}
...
}
That's It!
I hope this will help you. :)

Resources