How to add extra logic on login condition in Laravel 5.2 - laravel

I just wanted to say if the user is not active, don't allow to login. I have made the controller as below, I am not sure what I am missing or what else I have to do here to make this work!
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Auth\Authenticatable;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware($this->guestMiddleware(), ['except' => 'logout']);
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
}
My thinking was authenticate() method should do the trick!

The below code worked for my case:
protected function getCredentials(Request $request)
{
return [
'email' => $request->input('email'),
'password' => $request->input('password'),
'active' => true
];
}
for Laravel 5.3 need to add following code to LoginController
protected function credentials(Request $request)
{
return [
'email' => $request->input('email'),
'password' => $request->input('password'),
'active' => true
];
}

i think you should create method to check if user passed your credentials, here's my suggestion :
protected function getCredentials(Request $request)
{
return [
'username' => $request->input('email'),
'password' => $request->input('password'),
'active' => true
];
}
and your login method:
public function login(Request $request) {
$this->validate($request,['email' => 'required|email','password' => 'required']);
if (Auth::guard()->attempt($this->getCredentials($request))){
//authentication passed
}
return redirect()->back();
}
hope you get basic idea.

In LoginController.php file write this function
protected function credentials(Request $request) {
$extraFields = [
'user_type'=> 'customer',
'user_entry_status' => 1
];
return array_merge($request->only($this->username(), 'password'), $extraFields);
}

Go to this path :
your-project-folder/vendor/laravel/framework/src/illuminate/Foundation/Auth/AuthenticatesUsers.php
$credentials=$request->only($this->loginUsername(), 'password');
$credentials['status'] = '1';
return $credentials;

Change getCredantials works fine, but it is good practice to let user know, that the account was suspended (credentials are OK, but the account status is not). You can easily override login method in Auth/LoginController.php to your own copy, add your own logic to login process and raise own exception.
in Auth/LoginController.php create login and sendAccountBlocked function
/*load additional classes to LoginController.php*/
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Auth;
public function login(Request $request){
//
$this->validateLogin($request);
//
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
//check user status
if (Auth::user()->user_status == 'A') return $this->sendLoginResponse($request);
// if user_status != 'A' raise exception
else {
$this->guard()->logout();
return $this->sendAccountBlocked($request);
}
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
//
}//
protected function sendAccountBlocked(Request $request){
throw ValidationException::withMessages([
$this->username() => ['Your account was suspended.'],
]);
}

Related

How to make validation response as json when using request class

I have these request file to register a new customer, I want to be the response json when the validation fails, how can I do that?
This is the request class
<?php
namespace App\Http\Requests\Validations;
use App\Http\Requests\Request;
class RegisterCustomerRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|min:3|max:255',
'email' => 'required|email|max:255|unique:customers',
'password' => 'required|string|min:6|confirmed',
'agree' => 'required',
];
}
}
And the registration function:
public function register(RegisterCustomerRequest $request)
{
$customer = Customer::create([
'name' => $request->name,
'email' => $request->email,
'password' => $request->password,
'accepts_marketing' => $request->subscribe,
'verification_token' => Str::random(40),
'active' => 0,
]);
// Sent email address verification notich to customer
$customer->notify(new EmailVerificationNotification($customer));
$customer->generateToken();
event(new Registered($customer));
return new CustomerResource($customer);
}
in your RegisterCustomerRequest you can override default method failedValidation as below
protected function failedValidation(Validator $validator)
{
if ($this->ajax()){
throw new HttpResponseException($this->respondWithError(419,'VALIDATION_ERROR',$validator->errors()));
} else{
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
}
also you can write your own response inside $this->ajax() like below
if ($this->ajax()){
return response()->json($validator->errors(),419);
}

Laravel action after registration of user

In my Laravel application, after a new registration, it connects automatically to this new account.
I just need to register and stay connected with the actual Auth Account. How can we change this default setting?
Because I'm creating new accounts in the application with the admin user.
Thank you
This is my registerController code:
use RegistersUsers;
protected function redirectTo()
{
if(Auth::user()->is_admin == 1){
return 'persons';
}
return '/persons';
}
public function __construct()
{
$this->middleware('auth');
}
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
}
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
In Registeruser.php I changed the function register to
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
Note please that I create new users using person.blade.php, and not /register
In your App/Http/Controllers/Auth/RegisterController you need to override the method register from RegistersUsers trait:
public function register(Request $request)
{
$this->validator($request->all())->validate();
event(new Registered($user = $this->create($request->all())));
$this->guard()->login($user);
return $this->registered($request, $user)
?: redirect($this->redirectPath());
}
This line: $this->guard()->login($user); is where the user gets logged in. You can either remove it or modify it to suit your needs.
Now if you want to redirect after registration to a certain place depending on type of user you'd need to replace protected $redirectTo to:
protected function redirectTo()
{
//You would need to modify this according to your needs, this is just an example.
if(Auth::user()->hasRole('admin')){
return 'path';
}
if(Auth::user()->hasRole('regular_user')){
return 'path';
}
return 'default_path';
}
On top of your file, add these:
use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;

Redirect too many times when using socialite laravel package in laravel 5.4

I have installed socialite package in my application but its not working properly.
In my login with linkedin button i have given url like below
href="{{ url('auth/linkedin') }}"
My route file is
Route::get('auth/linkedin', 'LinkedInController#redirectToLinkedin');
Route::get('/linkedin/callback', 'LinkedInController#handleLinkedinCallback');
LinkedInController.php is
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Auth;
use Socialite;
use Exception;
class LinkedInController extends Controller {
protected $redirectTo = '/';
//use Illuminate\Foundation\Auth\AuthenticatesUsers;
public function __construct()
{
//$this->middleware('guest', ['except' => 'logout']);
}
protected function validator(array $data) {
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
protected function create(array $data) {
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
public function redirectToLinkedin() {
return Socialite::driver('linkedin')->redirect();
}
public function handleLinkedinCallback() {
try {
$user = Socialite::driver('linkedin')->user();
$create['name'] = $user->name;
$create['email'] = $user->email;
$create['linkedin_id'] = $user->id;
$userModel = new User;
$createdUser = $userModel->addNew($create);
Auth::loginUsingId($createdUser->id);
return redirect('/index');
} catch (Exception $e) {
return redirect('auth/linkedin');
}
}
}
After i clicking login with linkedin it will comes to redirectToLinkedin() function but i got error like
This page isn’t working
localhost redirected you too many times.
Try clearing your cookies.
ERR_TOO_MANY_REDIRECTS
Whats a problem with my code?

Laravel 5.3: How to authenticate only active users

I want to laravel 5.3 loged in users table status='Active' but status='Inactive' can't loged in.
Please help me with that. Thanks a lot guys!
Go to \vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
then change credentials functions.
And see this link https://laracasts.com/discuss/channels/laravel/allowing-only-active-users-to-login.
example function link
protected function credentials(Request $request)
{
$crendentials = $request->only($this->username(), 'password');
$crendentials['status']='Active';
return $crendentials;
}
Add this function in Auth/LoginController.php
use Illuminate\Http\Request;
protected function credentials(Request $request)
{
return [
$this->username() => $request->get($this->username()),
'password' => $request->get('password'),
'active' => 1
];
}
By doing this, you actually override it. This function is in the AuthenticatesUsers trait.
Another way for getting the same result is to override the validateLogin() function by adding
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => [
'required',
Rule::exists('users')->where(function ($query) {
$query->where('active', 1);
}),
],
'password' => 'required',
]);
}
to the LoginController.php
You can try like this:
if (Auth::attempt(['email' => $email, 'password' => $password, 'status' => 'Active'])) {
// The user is active, not suspended, and exists.
}

Laravel 5 auth always results false?

Here its my controller for logging in. the register controller works well, it creates an user to database but when i try to log in with it fails it results always false pls help.
namespace App\Http\Controllers;
use Auth;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\User;
class loginController extends Controller
{
public function login(Request $request)
{
$_email = $request->input('emaillogin');
$_password = $request->input('passwordlogin');
if (Auth::attempt(['email' => $_email, 'password' => $_password])) {
Auth::login(Auth::user());
return redirect()->intended('/dashboard');
}
else {
return redirect()->intended('/');
}
}
}
Auth::attempt logs user into your application if passed, no need for second authentication
if (Auth::attempt(['email' => $_email, 'password' => $_password])) {
return redirect()->intended('/dashboard');
} else {
return redirect()->guest('/login');
}
As i said in the comment and i just tested it on my local pc, maybe it's wrong to you but for me it doesn't work if i use plain password save in database, here's my register file
protected function create(array $data)
{
$activation_code = str_random(60);
$user = User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'activation_code' => $activation_code
]);
if ($user->save()) {
$data = array(
'name' => $user->username,
'code' => $activation_code,
);
\Mail::queue('emails.activate', $data, function($message) use ($user) {
$message->to($user->email)->subject('Thank you for registering. Please activate your account!');
});
}
return $user;
}
you see i have crypted password
'password' => bcrypt($data['password']),
and if i test it just with:
'password' =>$data['password'],
The registration works but authentication fails because password must be encripted you should also remove Auth::login(Auth::user()); that is not necessary
if (Auth::attempt(['email' => $_email, 'password' => $_password])) {
return redirect()->intended('/dashboard');
}
This happens on my site when i don't use bcrypt on password in registration controller and try to login later
Whoops! There were some problems with your input.
These credentials do not match our records.
Also what i have seen from our login form inputs are not emaillogin and passwordlogin they are just email and password

Resources