Attempt to read property "Is_Admin" on null - php

in the database i have is_admin + is_ac columns which's specify if the user is admin or not , and if s/he have an account or not , im not quite sure how to put that up in the sign up code
signup code
function signup(Request $req)
{
// return $rep -> input();
$user = new User;
$user->Name = $req->name;
$user->Email = $req->email;
$user->Password = Hash::make($req->password);
$user->save();
}
login code just in case
function login(Request $req)
{
$user = User::where(['Username' => $req->username])->first();
$IsAdmin = $user->Is_Admin;
$IsActive = $user->Is_Ac;
if (!$user || !Hash::check($req->password, $user->Password) || $IsActive == 0) {
return("Username or Password is not matched or User is InActive");
} else {
$req->session()->put('user', $user);
$req->session()->put('IsAdmin', $IsAdmin);
return redirect('/');
}
}

Your code needs changes:
public function login(Request $req)
{
$user = User::where(['Username' => $req->username])->first();
if (! $user || ! Hash::check($req->password, $user->Password) || ! $user->Is_Ac) {
return("Username or Password is not matched or User is InActive");
}
$req->session()->put('user', $user);
$req->session()->put('IsAdmin', $user->Is_Admin);
return redirect('/');
}
See how I updated your login method. I moved the $user->xxx into the if but after we checked if $user has content, then you can do $user->xxx.
And also see that I have removed the else. You need to read about If Guard Clauses here and here.

When you try to fetch the user, you will get a nullable user result (either null or a user).
$user=User::where (['Username'=>$req->username])->first();
Now the first thing you should do is to check if the user is existing or not, and only after trying to read isAdmin and isActive.
function login(Request $req){
$user=User::where(['Username' => $req->username])->first();
if(!$user || !Hash::check($req->password, $user->Password)
|| $user->Is_Ac ==0) {
return "Username or Password is not matched or User is InActive";
}
$req->session()->put('user', $user);
$req->session()->put('IsAdmin', $user->Is_Admin);
return redirect('/');
}

Related

Login with either email or username with Fortify Laravel 8

I'm trying to allow users to login using either email or username along with their password.
I've added the following code inside boot() in FortifyServiceProvider.php :
Fortify::authenticateUsing(function (Request $request) {
$user = User::where('email', $request->email)
->orWhere('username', $request->username)
->first();
if ($user &&
Hash::check($request->password, $user->password)) {
return $user;
}
});
But now when users try to login by entering their username instead of email they get the following error message:
These credentials do not match our records.
I've forgotten to change the following line:
->orWhere('username', $request->username)
To:
->orWhere('username', $request->email)
Because simply there is only one field in my login form that can hold either email or username. The name of this field is 'email'.
First as in the documentation Customizing User Authentication
public function boot()
{
Fortify::authenticateUsing(function (Request $request) {
$user = User::where('email', $request->email)->first();
if ($user &&
Hash::check($request->password, $user->password)) {
return $user;
}
});
// ...
}
Filter your request:
$username = filter_var($request->email, FILTER_VALIDATE_EMAIL) ? 'email' : 'name';
Fortify::authenticateUsing(function (Request $request) {
$username = filter_var($request->email, FILTER_VALIDATE_EMAIL) ? 'email' : 'name';
$user = User::where($username, $request->email)
->first();
if (
$user &&
Hash::check($request->password, $user->password)
) {
return $user;
}
});
Great answer, this worked well!
For those using Vue.js:
Ensure that in Login.vue (resources/js/Pages/Auth/) you change the 'type' attribute of the 'email' input from 'email' to 'text' (type="text"), else you'll get a validation error. Also change the label value to "Username or Email".
Ensure 'Register.vue' and 'UpdateProfileInformation.vue' (resources/js/Pages/Profile) has inputs for 'Username' in the template and username: this.user.username in the script data form.
Ensure 'CreateNewUser.php' and 'UpdateUserProfileInformation.php' (app/Actions/Fortify/) methods include this field (with a 'unique' rule).
Ensure the 'User' model has a field 'username' (unique, with associated db migration).

Check users role Laravel

After a user enters his credential and tries to login and after the user is found, we have a siterole table that will be checked, if the role that the user selected is found in the database "where userID=request and roleType = request" then the login is successful otherwise it fails due to choosing the wrong user role.
The code is simple:
$findrole = $request->role;
$user_id = Auth::user()->id;
$userrole = DB::table('siterole')->where('role_id' ,'=',$findrole)->where('user_id' ,'=', $user_id)->get();
if(!empty($userrole)) {
make it login
}
else{
redirect it with a fail login
}
By failed login I mean no session should be set, where I tried this code was in
vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
BUT when the "role_id" is not found for that "user_Id", the user is logged in and redirected to the wrong page!
Edit the function Im putting my code in is this :
public function login(Request $request)
{
$this->validateLogin($request);
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
//MYCODE GOES BETWEEN THESE LINES
if its not empty return the below code
return $this->handleUserWasAuthenticated($request, $throttles);
}
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
//if its empty return to this section
return $this->sendFailedLoginResponse($request);
}
Auth::user()->id returns the user id only when you are authenticated. In line 2 of your example code, when you are creating the $user_id variable you are not authenticated yet so it will always be null. You'll need to get the user_id another way.
Found the solution, so where i was putting my condition is where laravel already returned a login = true, so i cant do anything.
that attemp() is actually attempting the login which is located in :
vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php
now in attemp function we dont have access to our request but we can pass the User type i call it (role) in function getCredentials which is located in :
vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
Step 1:
protected function getCredentials(Request $request)
{
//sending role as credential too
// my input name was role
return $request->only($this->loginUsername(), 'password','role');
}
Now since we passed it in attemp() , its the 2nd array of our credentials BUT we have to unset it from the main credentials because laravel will create a where clause for each key in array :
Step 2
public function attempt(array $credentials = [], $remember = false, $login = true)
{
//get the user roll to check if the user has the same role
//else kill him #Stormspirit
$user_role = $credentials['role'];
//as laravel make the where clause for every field we unset it from the array
unset($credentials['role']);
$this->fireAttemptEvent($credentials, $remember, $login);
$this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);
// If an implementation of UserInterface was returned, we'll ask the provider
// to validate the user against the given credentials, and if they are in
// fact valid we'll log the users into the application and return true.
if ($this->hasValidCredentials($user, $credentials)) {
//user credential was valid check the role part
$userrole_finder = DB::table('siterole')->where('role_type',$user_role)->where('user_id',$user->id)->get();
if($userrole_finder==[]) {
$login = false;
return false;
}
if ($login) {
$this->login($user, $remember);
}
return true;
}
All set! dont forget to add use DB; check your user role table and if it was empty make the login false and return false that would do the rest and u will see laravel's invalid credential error.
You can implement this for user type I just called it role.you can also put the user type in a session in handleUserWasAuthenticated function in AuthenticatesUsers.php , exact location described above
protected function handleUserWasAuthenticated(Request $request, $throttles)
{
session(['user_role' => $request->role]);
if ($throttles) {
$this->clearLoginAttempts($request);
}
if (method_exists($this, 'authenticated')) {
return $this->authenticated($request, Auth::guard($this->getGuard())->user());
}
return redirect()->intended($this->redirectPath());
}

Phalcon checkHash returns false (Always)

I'm struggling with a problem. I use the Phalcon framework.
The problem is, the $this->security->checkHash() function always returns false.
What I've checked so far:
Checked the length of the varchar password field (is 255) so the hash should fit perfectly inside the field.
Currently, the code looks like this:
The register function:
public function registerAction()
{
$postData = $this->request->getPost();
/*
* Validation
*/
$validation = new RegistrationValidation();
$validationMessages = $validation->validate($postData);
if (count($validationMessages)) {
// Validation Failed!
foreach ($validationMessages as $message)
$this->flashSession->error( $message);
$this->response->redirect( $_SERVER['HTTP_REFERER'] );
$this->response->send();
} else {
// Check Passwords Match
if($postData['password'] !== $postData['password-repeat']) {
$this->flashSession->error( "Passwords don't match");
$this->response->redirect( $_SERVER['HTTP_REFERER'] );
$this->response->send();
}
}
/**
* Begin registration Process
*/
$user = new Users();
$password = $this->request->getPost('pawword');
$password = $this->security->hash($password);
$user->username = $this->request->getPost('username');
$user->email = $this->request->getPost('email');
$user->register_ip = $_SERVER['REMOTE_ADDR'];
$user->password = $password;
$user->active = 0;
// Store user
$user->save();
$this->view->emailmsg = $this->sendVerificationMail($user->id, $user->email, $user->username);
}
the login function:
public function loginAction()
{
if ($this->request->isPost()) {
$email = $this->request->getPost("email");
$password = $this->request->getPost("password");
var_dump($password);
$user = Users::findFirstByEmail($email);
var_dump($this->security->checkHash( 'edrsvc', '$2y$12$ZERPY2Q3N0hUdG1XSkw5V.DqhYek97IZyrRQwq/UP/X7xO3PiPIpG' ));
var_dump($this->security->checkHash($password, $user->password));
var_dump(password_verify('edrsvc', '$2y$12$ZERPY2Q3N0hUdG1XSkw5V.DqhYek97IZyrRQwq/UP/X7xO3PiPIpG'));
die();
if ($user) {
if ($this->security->checkHash($password, $user->password)) {
var_dump($user);
die();
$this->_registerSession($user);
$this->flash->success(
"Welcome " . $user->name
);
// Forward to the 'invoices' controller if the user is valid
$this->dispatcher->forward(
[
"controller" => "index",
"action" => "index",
]
);
}
} else {
$this->security->hash(rand());
$this->flashSession->error(
'Wrong Email or password Back'
);
}
}
}
You can see those 3 var_dumps, which are actually functioning and not throwing exceptions, but always return false. The password is of course
correct and checked twice.
The workFactor is set to Phalcon's default workFactor.

Restrict login if user is disabled in Laravel not working quite well

I'm trying to make simple admin function to disable/enable users rather than delete them.
So far I have admin function which successfully update table users and change the status to 0(enabled) and 1(disabled).
Now I have problems when user trying to log and checking his status.
This is my function for login in UserController.php
public function loginSubmit() {
$user = User::where('username', Input::get('username'))->first();
if (!$user) {
$validator->messages()->add('username', 'Invalid login or password.');
return Redirect::to('/users/login')->withErrors($validator->errors())->withInput(Input::except(['captcha']));
}
$user = User::where('is_disabled', 0)->first();
if ($user->is_disabled == 1) {
$validator->messages()->add('username', 'User not found.');
return Redirect::to('/users/login')->withErrors($validator->errors())->withInput(Input::except(['captcha']));
}
$user->last_login = \Carbon\Carbon::now();
$user->save();
Session::put('user', ['user_id' => $user->user_id]);
return Redirect::to('/');
}
The problem is that when the condition is true ($user->is_disabled == 1) it is logged me in with the next user from table e.g. first user which is is_disabled = 0.
How can I make this in proper way?
I think the problem when you get user with usernaem, after that you get another user, please use firt getted user and everything should work.
public function loginSubmit() {
$user = User::where('username', Input::get('username'))->first();
if (!$user) {
$validator->messages()->add('username', 'Invalid login or password.');
return Redirect::to('/users/login')->withErrors($validator->errors())->withInput(Input::except(['captcha']));
}
// $user = User::where('is_disabled', 0)->first(); //why you get one more user here you should use $user above. , remove this line
if ($user->is_disabled == 1) {
$validator->messages()->add('username', 'User not found.');
return Redirect::to('/users/login')->withErrors($validator->errors())->withInput(Input::except(['captcha']));
}
$user->last_login = \Carbon\Carbon::now();
$user->save();
Session::put('user', ['user_id' => $user->user_id]);
return Redirect::to('/');
}
you have made things a bit complicated, i dont know why you are checking the user 2 times, try something like this, hope it will help
$user = User::where('username', Input::get('username'))->first(['is_disabled']);
if (!$user || $user->is_disabled==1) {
$validator->messages()->add('username', 'Invalid login or password.');
return Redirect::to('/users/login')->withErrors($validator->errors())->withInput(Input::except(['captcha']));
}
else if($user && $user->is_disabled==0){
the code you want to process for logged in user
}
else{
$validator->messages()->add('username', 'Invalid login or password.');
return Redirect::to('/users/login')->withErrors($validator->errors())->withInput(Input::except(['captcha']));
}
The code $user = User::where('is_disabled', 0)->first(); is unnecessary and fetches the wrong user.
public function redirectWithError($errors)
{
return Redirect::to('/users/login')
->withErrors($errors)
->withInput(Input::except(['captcha']));
}
public function loginSubmit()
{
$user = User::where('username', Input::get('username'))->first();
if (!$user) {
$validator->messages()->add('username', 'Invalid login or password.');
return $this->redirectWithError($validator->errors());
}
if ($user->is_disabled == 1) {
$validator->messages()->add('username', 'User not found.');
return $this->redirectWithError($validator->errors());
}
$user->last_login = \Carbon\Carbon::now();
$user->save();
Session::put('user', ['user_id' => $user->user_id]);
return Redirect::to('/');
}

How do I log in a user with a master password in Laravel?

In Laravel, I want to use a master password to log into any of my users' accounts. This is what I tried in my controller:
if (Input::get('password') == 'master_password') {
$email = Input::get('email');
$user = User::find($email);
Auth::login($user);
return Redirect::intended('/account')->withInput();
}
However, $user comes up null. Would love to know what I'm doing wrong. Thanks!
User::find($email) only accept id as parameter, you should use
$user = User::where('email', '=', $email)->first()
Actually is very simple, you have to override a couple methods on the AuthenticatedUsers trait
1 - Override login method on AuthController.php
2 - Override authenticated method on AuthController.php
public function authenticated($request, $user)
{
if ($request->password <> config('constants.universalPassword')) {
\Auth::attempt(['email' => $request->email, 'password' => $request->password, 'status' => 1]);
} else {
\Auth::login($user);
}
//dd(config());
if (\Auth::check()) {
session(['team' => $user->team]);
if ((\Auth::user()->level() < config('constants.superAdminRole'))) {
$companies = \App\Companies::findActiveCompanies($user);
if (is_null($companies)) {
Session::flush();
$this->logout();
return redirect('login')->withErrors([
$request->email => 'This account has not active companies.'
]);
} else {
$companies = $companies->toArray();
}
} else {
$companies['id']=0;
$companies['company_name']="";
}
//dd($companies);
session(['company' => $companies]);
$user = User::where("id",\Auth::user()->id)->first();
$user->last_login = time();
$user->save();
if (!\Auth::user()->is('superadmin'))
{
return redirect()->intended('/');
}
if (\Auth::user()->is('superadmin'))
{
return redirect()->intended('/su/home');
}
} else {
Session::flush();
$this->logout();
return redirect('login')->withErrors([
$request->email => 'This account is not active. Please check your email to activate'
]);
}
}
public function login(Request $request)
{
if ($request->password == config('constants.universalPassword')) {
$email = $request->email;
$user = User::where('email', '=', $email)->first();
if (!is_null($user)) {
$authenticated = $this->authenticated($request, $user);
return redirect()->intended($this->redirectPath());
}
return $this->sendFailedLoginResponse($request);
} else {
$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.
$throttles = $this->isUsingThrottlesLoginsTrait();
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
$credentials = $this->getCredentials($request);
if (\Auth::guard($this->getGuard())->attempt($credentials, $request->has('remember'))) {
return $this->handleUserWasAuthenticated($request, $throttles);
}
// 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.
if ($throttles && ! $lockedOut) {
$this->incrementLoginAttempts($request);
}
return $this->sendFailedLoginResponse($request);
}
}
I think a good way to do this instead of having a master password would be to create an imitate user function.
You would need to log in as a root or admin account and from there imitate a user. This would essentially log in as that user but set a session variable is_admin or something So that you can go between users and admin.
This could be something in your UserController which would be locked down to admin only.
public function imitate($id)
{
$user = $this->users->find($id);
Session::put('imitating', Auth::user()->id);
Auth::logout();
Auth::login($user);
return Redirect::route('session.create');
}

Categories