New hashing of password - redirect users to password reset on login attempt - laravel

Here is an "update" In the previous version of my project we didn't have any proper hashing on password. So I want to use Laravel's hashing, and invite the users to make a new password.
What I have is a new password column in my User table. If when the user tries to log in, the new password doesn't exist (empty column), we automatically do a "reset password." I would like to know where to do this verification:
class LoginController extends Controller
{
public function login(Request $request)
{
//check if the user has an empty password
//if yes
redirect('/password/reset');
//else
//use normal login function
}
}
Is that the correct place? And do I need to rewrite all login content in the "else" ? (sorry this is a basic question)

I suggest that you create a middleware ( EnsurePasswordIsAdded as an example ) for your case and not include the verification process in a controller, because a controller usually contains functions that interact either a database or an external API to provide a response to the user which is not the case for you, you're just filtering/verifying the request.
here's the documentation link about middlewares in Laravel:
https://laravel.com/docs/5.8/middleware
here's a code suggestion:
public function handle($request, Closure $next)
{
if ( !User::find($request->email)->hasPassword() ) {
return redirect('password-reset')->with('email',$request->email);
}
return $next($request);
}

Related

How to hide login form after reaching the total of failed login attempts?

I want to hide the login form and display an error message instead, but I can't.
I tried to put the code below that rewrites the action on the controller that shows the form, but the method that checks for too many login attempts doesn't seem to work and never returns true.
public function showLoginForm(Request $request)
{
if (method_exists($this, 'hasTooManyLoginAttempts') &&
$this->hasTooManyLoginAttempts($request) ) {
$seconds = $this->limiter()->availableIn($this->throttleKey($request));
return view('auth.block', array(
'seconds' => $seconds
));
}
return view('auth.login');
}
I managed the authentication process with php artisan make: auth login controller is the default generated by Laravel, the only change is in the action that displays the form.
The function hasTooManyLoginAttempts() needs, in the $request, the username (usually the email) as a key to know if the user has reached his max login attempts.
If, in the $request, there is not the username with a value the function is unable to verify the user login attempts.
So you cannot really know who is the user that wants to get your login form, you know who is only after he submitted the form.
IMHO the only way could be to add a username parameter to the GET request but you shoud provide it with some workarounds: cookies, session etc.
Looking at Laravel's code, it checks for hasTooManyLoginAttempts based on throttleKey and maxAttempts.
The throttleKey is dependent on the user's email and IP address. So the output of the following code is something like: info#example.com|127.0.0.1 and that is your throttleKey.
protected function throttleKey(Request $request)
{
return Str::lower($request->input($this->username())).'|'.$request->ip();
}
Now Laravel gets the user's email (username) from $request->input($this->username()) when you send a POST request, which you don't have access to in the showLoginForm method because it's called on the GET request.
Anyway, if you want to block the login form you'll need to come up with your own unique throttleKey and then override the method. Say you want your throttleKey to be based only on the IP address - which is not recommended. Here's how you do it:
// In LoginController.php
protected function throttleKey(Request $request)
{
return $request->ip();
}

How to send a random generated number along with email and password while logging in with laravel 5.6

I want to send a random generated number along with password and email field when the user is logging and attach that number where laravel is grabbing the user password (i want to attach the random number to the password that laravel grabs from the user table then check it against the password that the user entered in the login field)
However i am not able to send the random number from the login blade in a hidden field. Please help
You can overwrite default login function of laravel and create your own to send extra data after logging in.
Below is the code to get random number in session after logging in. Implement in your Controllers\Auth\LoginController.php .
class LoginController extends Controller
{
use AuthenticatesUsers {
login as traitLogin
}
public function login(Request $request)
{
$randomNumber = mt_rand();
$request->session()->flash('random_number', $randomNumber);
return $this->traitLogin($request);
}
}
After that, if you wish to use it in HomeController then you can do as below,
class HomeController extends Controller
{
public function index(Request $request)
{
$form = $request->session()->get('form_type');
// the rest of your logic
}
}
Note: If you want to use random number anywhere else, then you have to specify the place where you want to use it.
Hope this helps!

Laravel 5.4 Authentication password reset redirect based on email address

I am involved in a web site using Laravel 5.4 and using the built-in authentication.
I have added a "Forgot Password" link that shows the ResetPasswordController#showLinkRequestForm which emails a password
reset link when submitted and then the ResetPasswordController#showResetForm redirects to the login page when submitted.
The problem I have is that we have two different Users - clients and admins. I have the ability to determine which is
which through the registered email address but I want the redirect following password reset be different for each type
(client = '/' and admin = '/admin').
How is this be done?
If you are using the ResetsPasswords trait in your controller, you can create your own redirectTo() method which will be called to redirect the user :
// import the needed trait
use Illuminate\Foundation\Auth\ResetsPasswords;
class YourResetPasswordController {
// use the needed trait
use ResetsPasswords;
// override the method that redirects the user
public function redirectTo()
{
if (auth()->user()->isAdmin()) {
return redirect('/admin');
} else {
return redirect('/');
}
}
}
Let me know if it helped you :)

Disabled user / Validation Email

I've added a column (is_activated) in user DB to add verification email in registration process.
I follow this tutorial:
Tutorial
It works but an user that is not activated can bypass login function using the reset password form.
How can I resolve this problem?
You should create middleware and redirect all not activated users back to home page, for example:
public function handle($request, Closure $next)
{
if (!auth()->user()->is_activated) {
return redirect('/');
}
return $next($request);
}
Then register this middleware and apply it to all non public routes with Route::group()
If user is activated the value is 1, so integrate in your function the next validation:
// if user not have value 1 (is not activated)
if (auth()->user()->is_activated != 1) {
// user is not activated so redirect to index
return redirect('/');
}
// user is activated so redirect to account
return redirect('account');
}
you need check is "is_actived" have the value 1 or not.

Laravel5.2 default auth check if user is verified in database before login and display custom message

I am using laravel5.2 auth and I have added an additional field : verified(y/n) in users table. Now before login I want to check if user is verified(Y) in database and if not verified display a message that your account is not yet verified.
If method authenticated exists in the AuthController it will be called from Laravel trait AuthenticatesUser. Use this method to block the user if it is not verified yet and, if required, resend the email.
public function authenticated(Request $request, $user)
{
if (!$user->activated) {
$this->activationService->sendActivationMail($user);
auth()->logout();
return back()->with('warning', 'You need to verify your account. We have sent you an activation code, please check your email.');
}
return redirect()->intended($this->redirectPath());
}
In /vendor/laravel/framework/src/Illuminate/Foundation/Auth you will find AuthenticatesAndRegistersUsers.php there you define what you want to do with your login.

Resources