Im new to laravel and i decided to make a little project to learn a bit and im trying to make a password reset function following this tutorial but the code seems to always update the first user no matter what. Even if user2#gmail.com tries to reset password, the password resets for user1#gmail.com.
Here is the code :
PasswordReset
public function forgotPassword(Request $request)
{
try {
$user = User::where('email', $request->email)->get();
if (count($user) > 0) {
$token = Str::random(40);
$domain = URL::to('/');
$url = $domain.'/reset-Password?token='.$token;
$data['url'] = $url;
$data['email'] = $request->email;
$data['title'] = "Password Reset";
$data['body'] = "Please click the link below to reset ur password";
Mail::send(
'forgetPasswordMail',
['data' => $data],
function ($message) use ($data) {
$message->to($data['email'])->subject($data['title']);
}
);
$datetime = Carbon::now()->format('Y-m-d H:i:s');
PasswordReset::updateOrCreate(
['email' => $request->email],
[
'email' => $request->email,
'token' => $token,
'created_at' => $datetime
]
);
return response()->json(['success' => true, 'msg' => 'Password Reset Sent']);
} else {
return response()->json(['success' => false, 'msg' => 'User not Found']);
}
} catch(\Exception $e) {
return response()->json(['success' => false, 'msg' => $e->getMessage()]);
}
}
public function resetPasswordLoad(Request $request)
{
$resetData = PasswordReset::where('token', $request->token)->first();
if ($resetData) {
$user = User::where('email', $resetData->email)->first();
if ($user) {
return view('resetPassword', ['user' => $user]);
}
}
return response()->json(['success' => false, 'msg' => 'error404']);
}
public function resetPassword(Request $request)
{
$request->validate([
'password' => 'required|string|min:6|confirmed',
'user_id' => 'required|integer'
]);
$user = User::find($request->user_id);
if ($user) {
$user->password = Hash::make($request->password);
$user->save();
PasswordReset::where('email', $user->email)->delete();
return "<h1>Password reset successfully</h1>";
} else {
return "<h1>Error: User not found</h1>";
}
}
view
#if($errors->any())
<ul>
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
#endif
<center>
<form method="POST" action="/reset-Password">
#csrf
<input type="hidden" name="user_id" value="{{ $user->id }}">
<input type="password" name="password" placeholder="New Password">
<br>
<br>
<input type="password" name="password_confirmation" placeholder="Confirm Password">
<br>
<br>
<input type="submit">
</form>
</center>
I tried switching between using the token and email to authenticate but that just made the code a mess.
I am new in Laravel too. I started with it 3 months ago. I have to say, I was to much for me to do whole reset password logic on my own at this stage.
So in created new temp project with Breeze (https://laravel.com/docs/9.x/starter-kits#breeze-and-blade), and I tried to understand the reset password by debugging it step by step via xdebug.
Then I implemented same logic in my project and it is working like a charm.
public function forgotPassword(Request $request): RedirectResponse
{
$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')
);
if ($status == Password::RESET_LINK_SENT) {
return back()->with('success', __($status));
}
throw ValidationException::withMessages([
'email' => [trans($status)],
]);
}
public function resetPassword(Request $request): RedirectResponse
{
$request->validate([
'token' => ['required'],
'email' => ['required', 'email'],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
// Here we will attempt to reset the user's password. If it is successful we
// will update the password on an actual user model and persist it to the
// database. Otherwise we will parse the error and return the response.
$status = Password::reset(
$request->only('email', 'password', 'password_confirmation', 'token'),
function ($user) use ($request) {
$user->forceFill([
'password' => Hash::make($request->password),
'remember_token' => Str::random(60),
])->save();
event(new PasswordReset($user));
}
);
// If the password was successfully reset, we will redirect the user back to
// the application's home authenticated view. If there is an error we can
// redirect them back to where they came from with their error message.
return $status == Password::PASSWORD_RESET
? redirect()->route('login')->with('success', __($status))
: back()->withInput($request->only('email'))
->withErrors(['email' => __($status)]);
}
public function resetPasswordLoad(Request $request): View
{
return view('auth.reset-password', ['request' => $request]);
}
View reset-password.blade.php:
<form method="POST" action="{{ route('password.store') }}">
#csrf
<div class="mx-auto d-block w-100">
<p class="login-form-title py-3">{{__('login.reset_password_header')}}</p>
</div>
<!-- Password Reset Token -->
<input type="hidden" name="token" value="{{ $request->route('token') }}">
<div class="form-floating my-3">
<input type="text" class="form-control" id="email" name="email" placeholder="email" value="{{old('email', $request->email)}}">
<label for="email">{{__('user.email')}}</label>
#error('email')
<span class="error-message">{{$message}}</span>
#enderror
</div>
<div class="form-floating my-3">
<input type="password" class="form-control" id="password" name="password" placeholder="Password" value="{{old('password')}}" required>
<label for="password">{{__('user.password')}}</label>
#error('password')
<span class="error-message">{{$message}}</span>
#enderror
</div>
<div class="form-floating my-3">
<input type="password" class="form-control" id="password_confirmation" name="password_confirmation" placeholder="Repeat your password" value="{{old('password_confirmation')}}" required>
<label for="password_confirmation">{{__('user.repeat_your_password')}}</label>
#error('password_confirmation')
<span class="error-message">{{$message}}</span>
#enderror
</div>
<!-- Submit button -->
<button type="submit" class="btn btn-primary btn-block mb-4 w-100">{{__('generic.submit')}}</button>
<div class="text-center">
<p>{{__('login.back_to_login')}}</p>
</div>
</form>
View: forgot-password.blade.php
<form method="POST" action="{{route('password.email')}}">
#csrf
<div class="mx-auto d-block w-100">
<p class="login-form-title py-3">{{__('login.forgot_password_header')}}</p>
<p class="login-form-subtitle">
{{__('login.to_reset_your_password')}}
</p>
</div>
<div class="form-floating my-3">
<input type="text" class="form-control" id="email" name="email" placeholder="email" value="{{old('email')}}">
<label for="email">{{__('user.email')}}</label>
#error('email')
<span class="error-message">{{$message}}</span>
#enderror
</div>
<!-- Submit button -->
<button type="submit" class="btn btn-primary btn-block mb-4 w-100">{{__('generic.submit')}}</button>
<div class="text-center">
<p>{{__('login.back_to_login')}}</p>
</div>
</form>
Related
I'm new to Laravel. I have created custom Change Password in Laravel 8 using Livewire. But, after succeeded in updating the user password, my session is expired and redirected to login page. So, the question is how to keep the session alive and redirect to the current page?
Here's my code:
ChangeUserPassword.php
class ChangeUserPassword extends Component
{
public $oldPassword;
public $newPassword;
public $confirmPassword;
public function render()
{
return view('livewire.auth.change-user-password');
}
public function changePassword()
{
$this->validate([
'oldPassword' => 'required',
'newPassword' => ['required', Password::min(8)
->letters()
->mixedCase()
->numbers()
->symbols()
// ->uncompromised()
],
'confirmPassword' => 'required|min:8|same:newPassword'
]);
$user = User::find(auth()->user()->id);
if (Hash::check($this->oldPassword, $user->password)) {
$user->update([
'password' => Hash::make($this->newPassword),
'updated_at' => Carbon::now()->toDateTimeString()
]);
$this->emit('showAlert', [
'msg' => 'Your password has been successfully changed.'
]);
return redirect()->route('user.changepassword');
} else {
$this->emit('showAlertError', [
'msg' => 'Old password does not match.'
]);
}
}
}
change-user-password.blade.php
<div class="col-md-12">
<div class="card">
<div class="card-body">
<h4 class="card-title ml-2">Change Password</h4>
<form wire:submit.prevent="changePassword" role="form">
#csrf
<div class="row">
<div class="form-group col-md-4">
<label for="oldPassword" class="form-label">Old Password<span style="color: red"> *</span></label>
<input class="form-control #error('oldPassword') is-invalid #enderror" wire:model="oldPassword" name="oldPassword" id="oldPassword" type="password" />
#error('oldPassword')
<small id="helpId" class="text-danger">{{ $message }}</small>
#enderror
</div>
<div class="form-group col-md-4">
<label for="newPassword" class="form-label">New Password<span style="color: red"> *</span></label>
<input class="form-control #error('newPassword') is-invalid #enderror" wire:model="newPassword" name="newPassword" id="newPassword" type="password" />
#error('newPassword')
<small id="helpId" class="text-danger">{{ $message }}</small>
#enderror
</div>
<div class="form-group col-md-4">
<label for="confirmPassword" class="form-label">Confirm Password<span style="color: red"> *</span></label>
<input class="form-control #error('confirmPassword') is-invalid #enderror" wire:model="confirmPassword" name="confirmPassword" id="confirmPassword" type="password" />
#error('confirmPassword')
<small id="helpId" class="text-danger">{{ $message }}</small>
#enderror
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary pull-right"
wire:loading.attr="disabled">Save</button>
{{-- <div wire:loading>
<img style="width: 25px;" src="{{ asset('assets/images/spinner-small.gif') }}" alt="Loading">
</div> --}}
</div>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('livewire:load', function (e) {
e.preventDefault()
})
</script>
Any suggestion would really help. Thanks.
Authenticate the user again after updating the password
if (Hash::check($this->oldPassword, $user->password)) {
$user->update([
'password' => Hash::make($this->newPassword),
'updated_at' => Carbon::now()->toDateTimeString()
]);
$this->emit('showAlert', [
'msg' => 'Your password has been successfully changed.'
]);
if(Auth::attempt(['email'=>$user->email, 'password'=>$this->newPassword])){
$request->session()->regenerate();
return redirect()->intended('user.changepassword');
}
} else {
$this->emit('showAlertError', [
'msg' => 'Old password does not match.'
]);
}
I want to make Laravel's "remember me" feature. The problem is that, whenever I create a remember_token column, I am unable to log in or register a user, as it gives some unknown error that I cannot find in any way. Also, I have no idea how to apply this functionality with my code.
Login and Registration Form (except that the registration form does not have a checkbox):
<form class="login-form needs-validation" method="POST" action="{{ route('loja.logar') }}" novalidate>
#csrf
<div class="form-group">
<input type="email" id="email" name="email" aria-describedby="emailHelp" placeholder="Email" required>
</div>
<div class="form-group">
<input type="password" id="password" name="password" placeholder="Password" required>
</div>
<div class="custom-control custom-checkbox mr-sm-2">
<input type="checkbox" name="remember" class="custom-control-input" id="remember">
<label class="custom-control-label" for="remember">Remember me</label>
</div>
<button type="submit" id="submit" name="submit">Enviar</button>
</form>
I'm not using Model, just a controller that is the SiteController:
public function logar(Request $req)
{
$data = $req->all();
$user = Auth::attempt(['email' => $data['email'], 'password' => $data['password']]);
$this->validate($req, [
'email' => ['required', 'email'],
'password' => 'required'
]);
if ($user) {
return redirect()->route('loja.index');
} else {
return redirect()->route('loja.login')
->with('status-verification', 'Error. Try again!');
}
}
public function regist(Request $req)
{
$data = $req->all();
$validator = $this->validate($req, [
'email' => [
'required',
'email',
function ($attribute, $value, $fail) {
if (Users::whereEmail($value)->count() > 0) {
echo 1;
}
},
]
]);
if ($validator) {
Users::create([
'email' => $data['email'],
'password' => Hash::make($data['password'])
]);
return redirect()->route('loja.register');
}
}
User Table:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id')->unique();
$table->string('email', 191)->unique();
$table->string('password');
});
}
I'm making a custom login in Laravel, and when I try to check login form's data I cannot log in. In register I hash the password to store it in db, so the login form's password field will never be equal to stored db.
Here's my create function, where I register the user:
public function create()
{
$this->validateFields();
if (request('profileImage') !== null) {
$this->storeImage();
User::create([
'username' => request('username'),
'email' => request('email'),
'password' => Hash::make('password'),
'profileImage' => request()->profileImage->getClientOriginalName(),
]);
}
User::create([
'username' => request('username'),
'email' => request('email'),
'password' => Hash::make(request('password')),
]);
return Redirect::to(route('user.showLoginForm'));
}
validateFields and storeImage are not relevant for the question...
Here's my login function:
public function login()
{
request()->validate([
'email' => 'required',
'password' => 'required'
]);
$credentials = array(
"email" => request("email"),
"password" => bcrypt(request("password"))
);
if (Auth::attempt($credentials)) {
return 'exit!';
}
return 'Error';
}
Here's my login form:
<div class="container">
<div class="row pt-2">
<div class="col-sm-12 justify-content-center">
<div class="card">
<div class="card-header">
<h4>
Login
</h4>
</div>
<div class="card-body">
<div class="form-group">
<form action="{{ route('user.login') }}" method="post" enctype="multipart/form-data">
#csrf
<div class="form-group row">
<div class="col-md-4 col-form-label text-md-right">
<label for="email">{{ __('E-mail') }}</label>
</div>
<div class="col-md-6">
<input type="email" name="email" id="email" class="form-control">
</div>
</div>
<div class="form-group row">
<div class="col-md-4 col-form-label text-md-right">
<label for="password">Contraseña</label>
</div>
<div class="col-md-6">
<input type="password" name="password" id="password" class="form-control">
</div>
</div>
<div class="form-group row">
<div class="col-md-6 col-form-label text-md-right">
<button type="submit" class="btn btn-outline-elegant">Iniciar sesión</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
Custom login 100% working without auth,
use Hash;
$data->password = Hash::make(($request->password)); Encript Password
public function requestEmployee(Request $request)
{
if ($data = AddEmployee::where('name', $request->name)->first()) {
$pass = Hash::check($request->password, $data->password);
if ($pass) {
echo "sucess";
} else {
echo "Password Not Valid";
}
} else {
echo "Username Not Valid" . "<br>";
}
}
$password=Hash::check($request->password,$user->password);
use this it will return true or false
Or
just use
$credentials = array(
"email" => request("email"),
"password" => request("password")
);
without bcrypt
Please try it:
public function login()
{
request()->validate([
'email' => 'required',
'password' => 'required'
]);
$credentials = array(
"email" => request("email"),
"password" => request("password")
);
if (Auth::attempt($credentials)) {
return 'exit!';
}
return 'Error';
}
I am Login my Backend page he is getting error Username and password does not match, But my email id and password are correct in MySQL Server.
What is the problem in my code? Why I don't log in my page. Thank you
AuthController.php
namespace App\Http\Controllers;
use App\Models\Block;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Session;
class AuthController extends Controller
{
public function getLogin(){
return view('login');
}
public function login(Request $request){
// dd($request->all());
if( Auth::attempt(['email' => $request->email, 'password' => $request->password])){
// login code here
return redirect('/');
}
Session::flash('danger', 'Username and password does not match');
return redirect('login');
// login failed here
}
}
'''
LoginBlade.php
'''
</head>
<body>
<div class="limiter">
<div class="container-login100">
<div class="wrap-login100 p-l-55 p-r-55 p-t-65 p-b-50">
<form class="login100-form validate-form" method="POST" action="{{URL::to('login')}}">
#csrf
#include('backend.layouts.alerts')
<span class="login100-form-title p-b-33">
Account Login
</span>
<div class="wrap-input100 validate-input #error('email') is-invalid #enderror " data-validate = "Valid email is required: valid#email.xyz">
<input class="input100" type="email" name="email" placeholder="Email" required>
<span class="focus-input100-1"></span>
<span class="focus-input100-2"></span>
</div>
#error('email')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
<div class="wrap-input100 rs1 validate-input" data-validate="Password is required" >
<input class="input100 #error('password') is-invalid #enderror" type="password" name="password" placeholder="Password" required>
<span class="focus-input100-1"></span>
<span class="focus-input100-2"></span>
</div>
#error('password')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
<div class="container-login100-form-btn m-t-20">
<button class="login100-form-btn" value="submit">
Sign in
</button>
</div>
</form>
</div>
</div>
</div>
The code you wrote isn't too far off, The most likely culprit for the issue you are having is how you register or create your user.
This would work provided somewhere in your Registration controller you are hashing the password using bcrypt() or Hash::make()
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function getLogin()
{
return view('login');
}
public function login(Request $request)
{
// validate your request
$credentials = $request->validate([
'email' => 'required|string',
'password' => 'required|string',
]);
if (auth()->attempt($credentials)) return redirect('/');
return redirect('login')
->with('danger', 'Username and password does not match');
}
protected function register(Request $request)
{
// validate your request
$data = $request->validate([
'name' => 'required|string',
'email' => 'required|string',
'password' => 'required|string',
]);
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
auth()->login($user);
return redirect('/');
}
}
I am creating a web site and I have a Registration form. So , when someone going to use a username and email which is already in the database , I want to show them a message " Username and Email already taken " like this. If username and email are unique , user can register. But , when I try to register someone , it always shows " Username and Email already taken ". I can't register even when I use unique data.
How can I Fix this ??
AdminPanel.blade.php
#if(session()->has('OnlyImg'))
<h4 class="alert alert-success"> {{ session()->get('OnlyImg') }} </h4>
#endif
<form class="form-horizontal" method="POST" action="{{ route('adinsert') }}" enctype="multipart/form-data">
{{ csrf_field() }}
<div class="form-group">
<label>Username : *</label>
<input type="text" class="form-control" name="username" value="{{ old('username') }}" placeholder="Enter Your Username" required>
</div>
<div class="form-group">
<label>Email : *</label>
<input type="email" class="form-control" name="email" value="{{ old('email') }}" placeholder="Enter Your Username" required>
</div>
<div class="form-group">
<label>Password : *</label>
<input type="password" class="form-control" name="password" value="{{ old('password') }}" placeholder="Enter Your Password" required>
</div>
<div class="form-group">
<label>Upload Profile Picture :</label>
<input type="file" class="form-control-file" name="file_img" aria-describedby="fileHelp">
<small id="fileHelp" class="form-text text-muted">If U Want , U Can Skip Upload A Profile Picture</small>
</div>
#section('btnName',"Insert")
<input type="submit" class="btn btn-primary" onclick="myFunction()" name="submit" value="#yield('btnName')">
</form>
AdminPanelController.php
public function adinsert(Request $request)
{
$username = $request->input('username');
$email = $request->input('email');
$password = bcrypt($request->input('password'));
//$passen = bcrypt($password);
$user = new User();
$user->username = $username;
$user->email = $email;
$user->password = $password;
$this->validate($request, [
'email' => 'required'
]);
$res = DB::table('users')->where(['username' => $username, 'email' => $email])->get();
if ($res > 0 ) {
$request->session()->flash('Msg', 'Email already taken , Use another Email !!');
return redirect('AdminPanel');
}
else
{
if(Input::hasFile('file_img')){
$file = Input::file('file_img');
$rules = array(
'file_img' => 'required|max:10000|mimes:jpeg,png,jpg'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
$request->session()->flash('OnlyImg', 'You Can Only Upload Images !!');
return redirect('AdminPanel');
}
else if ($validator->passes()) {
$fileimg = $file->getClientOriginalName();
$destinationPath = 'img/Admins/';
$filemove = $file->move($destinationPath, $fileimg);
$user->fileimg = $fileimg;
$user->filemove = $filemove;
$user->save();
$request->session()->flash('Msg', 'Successfully Inserted !!');
return redirect('AdminPanel');
}
}
else
{
$user->save();
$request->session()->flash('Msg', 'Successfully Inserted !!');
return redirect('AdminPanel');
}
}
}
Here is Route.
Route::post('adinsert',[
'uses'=> 'AdminPanelController#adinsert',
'as' => 'adinsert'
]);