laravel 5.2 user login with active status - laravel

hi every one i am using laravel 5.2 default auth but i want that the user must only be logged in with active status.
https://laravel.com/docs/5.2/authentication
in this link they given the method like the following
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
}
but I did not find this where it is located in laravel 5.2.
I searched but the solutions are for previous versions and not for 5.2.
So please help me to login the users that has active status only so give me laravel 5.2 not of 5.1 or previous versions built in or custom solution to solve the problem

Assuming you are using the default auth setup, you can override the getCredentials method on the AuthController, which comes from the AuthenticatesUsers trait.
protected function getCredentials(Illuminate\Http\Request $request)
{
return $request->only($this->loginUsername(), 'password') + ['active' => 1];
}
That method returns the credentials array that is passed to Auth::attempt in the login method of AuthController. As other people have mentioned you will need to have a active field on your users table.

That example is only to show you can add custom fields when attempting to login.
You need to add an extra field to your User table like isActive.
When you have done this you can check if a user is active in your application.
if($user->isActive) {
// do something
}

Related

Custom login property Laravel 8

I have this custom function for atempting to login in Laravel 8
protected function attemptLogin(Request $request)
{
$credentials = $this->credentials($request);
$credentials['estado']=1;
return $this->guard()->attempt(
$credentials, $request->filled('remember')
);
}
How I can make to accept the login atempt when $credentials['estado'] also has 2 as value.
Don't know how to make it accept multiple values.
I managed to make the custom function accept the value of 1 but dunno how to make it accept multiple $credentials['estado'] values.
You don't need to change anything in attemptLogin() method, instead you can customize the crededentials() method in LoginController like this:
// login, if user have like a following described data in array
protected function credentials(Request $request)
{
$username = $this->username();
return [
$username => $request->get($username),
'password' => $request->get('password'),
'estado' => [ 1, 2 ], // OR condition
];
}
Answer for comments:
Honestly in my experience I didn't have that case, but if you want to redirect to the another view on failed login (for specific field 'estado'), you can customize the "sendFailedLoginResponse" method, and add some additional if-condition for checking the 'estado'.
As the "sendFailedLoginResponse" method will be called only for getting failed login response instance, then you can check: is that fail comes from 'estado' field actually. Something like this:
protected function sendFailedLoginResponse(Request $request)
{
// custom case, when login failed and estado is 2
if ($request->get('estado') == 2) {
return view('some.specific.view');
}
// laravel by default implementation
else {
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
}
Remember, in this case (when we're redirecting the user to some page) we actually not redirecting as for always, but instead we're just returning a view. We do that because I think you don't want to let the users to open that specific view page anytime their want, as you need to let them see that page only for specific case. But when you'll do the actual redirect, then you will let the users to visit that page with some static URL.
Of course, you can do some additional stuff (add something in DB or the Session, and check is the request comes actually from 'estado' fails, but not from any user), but this could be a headeche for you, and in my opinion that will not be a real laravel-specific code.
Anyway, this is the strategy. I don't think, that this is mandatory, but this can be do your work easy and secure.
Note: I've got this deafault implementations from "AuthenticatesUsers" trait (use use Illuminate\Foundation\Auth\AuthenticatesUsers;). In any time you can get some available methods from there and override them in your LoginController, as the LoginController used that as a trait.

Laravel Passport custom validation for any /oauth/token request

I need to validate extra fields in my users table before i create the requested tokens, but i can't find a simple way to do it with Passport.
I find similar workarunds which returns a token using $user->createToken() but i can't find someone covering all default /oauth/token options like the refresh_token
Also i see Passport have some simple ways to customize the username column and the password validation but i think this not cover my neededs.
Update
Im not sure if this is the best solution but in Laravel 5.8 the passport package have this validateForPassportPasswordGrant() function which allow you to add some extra conditionals before allowing the authentication process to get completed.
class User extends Authenticatable
{
public function validateForPassportPasswordGrant($password)
{
if ($this->active != true) {
throw OAuthServerException::accessDenied('The account is not active');
}
return Hash::check($password, $this->password);
}
}
In your login method
if (Auth::attempt(['email' => $request->email, 'password' => $request->password, 'is_active' => 1, 'username' => $request->username])) {
// create a token here
}

Password resetting in laravel when email address is not unique

This might sound like an antipattern or a weak system design, but the client of my app has demanded that there can be multiple users with same email address.
So I added another unique column named username to the users table and removed ->unique() constraint from email column.
Registration, Login are working fine but the problem arises during the password reset.
Consider the scenario:
username - johndoe, email - john#example.com
username - janedoe, email - john#example.com
username - jimmydoe, email - john#example.com
If any one of them makes a request for a password reset link, they would have to use johndoe#example.com as their email. So which user's password is actually going to be reset when they click on reset link from mail? Turns out, the first user, in this case, johndoe. Even if the request was made by janedoe or jimmydoe.
So how do I reset password for a single username, rather than an email? What changes should I make in the ForgotPasswordController and/or ResetPasswordController controllers to solve this? Or, do I have to make changes in the core framework? If so, where and how?
Tested in Laravel 5.3 [This answer modifies some core files(you may override it if capable) and it's not a clean solution.]
Ask user for the unique username value instead of email on password forget form.
Override the sendResetLinkEmail() method in ForgotPasswordController.php as folows. [Originally written in SendsPasswordResetEmails.php].
public function sendResetLinkEmail(Request $request)
{
$this->validateEmail($request);
$response = $this->broker()->sendResetLink(
$request->only('username')
);
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
you would also need to override the validateEmail() method.
protected function validateEmail(Request $request)
{
$this->validate($request, ['username' => 'required']);
}
Add username field instead of email on password reset form.
Override rules() in ResetPasswordController.php to over come the email field change.
protected function rules()
{
return [
'token' => 'required',
'username' => 'required',
'password' => 'required|confirmed|min:6',
];
}
Also override the credentials() in ResetPasswordController.php
protected function credentials(Request $request)
{
return $request->only(
'username', 'password', 'password_confirmation', 'token'
);
}
Update or override the getEmailForPasswordReset() method in Illuminate\Auth\Passwords\CanResetPassword.php to the folowing.
public function getEmailForPasswordReset()
{
return $this->username;
}
Laravel uses key-value pair to find the user and send email. If you pass 'username => 'xyz' it will look for the first record with value 'xyz' in username field.
Note: The unique column in users table is expected as username.
Illuminate\Auth\Passwords\CanResetPassword.php is a trait, and I was not able to overide the getEmailForPasswordReset method, so i just modified the core file itself.
This might sound like an antipattern or a weak system design, but the client of my app has demanded that there can be multiple users with same email address.
Then you need to rewrite this feature and ask user for some more unique information, no matter what it is going to be. Laravel provided password reset expects email to be unique and with your current design it won't work. There's no magic here. You you cannot disambiguate your user using non unique data.
You will need to rework some things for this, but I feel like the user experience is better. Generate a unique key for each user (for data hiding). There is a helper method for creating unique keys.
Then, when the email is sent out, link the button to a route that utilizes this key.
Then, modify or create that route that points to the reset password controller. You would then know which user it was referring to.
Remove the need for the user to insert their password because you'd already know who it was.

Laravel 5.4 show activation pending message on login form

I am working on Laravel 5.4 project. I love the login provided by Laravel and it works fine with both login or register.
I add below code to Auth/LoginController.php. It allows only activated users (status=1) to successfully login, but not pending users or blocked users (status =0 or something else).
protected function credentials(\Illuminate\Http\Request $request)
{
return ['email' => $request->{$this->username()}, 'password' => $request->password, 'status' => 1];
}
Anyway, to protect spam I would like to allow only activated users to login. For those whose account are not activated, I would like to show the pending message on the login form. Also, I would like to do the same thing for blocked users.
Could you please advise me how to achieve this?
This way Laravel would only pick only users by the credentials you specify, if you want to check status the user has and what view to show you can overwrite the authenticated() method of the login controller. It will have access to the already logged in user so note that you have to logout it the status is invalid.
protected function authenticated(Request $request, $user)
{
if ( $user->status == 0 ) {
auth()->logout();
return back()->withErrors(['email' => 'You are blocked or not activated.']);
}
return redirect()->intended($this->redirectPath());
}

Pass user id in laravel after logged in

I would like to pass / submit the user_id of the currently logged on user. How will I do it in laravel 5.2? Please need help
I am not sure on my code on how will I use Auth:user() blah blah. Need help with this. I am new to this.
You can use the login functionality like this and pass the datas to the required pages as per your wish.
public function Dologin()
{
// create our user data for the authentication
$userdata = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
);
if (Auth::attempt($userdata))
{
$user_id=Auth::user()->user_id;// user_id it will change as per the users table in your project.
return redirect('index');
}
else
{
}
}
Make sure you save your password using bcrypt method and for that alone the Auth::check() and Auth::user() will work.
auth()->id() will provide the user id

Resources