Check users role Laravel - php

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());
}

Related

Cant test if a database boolean is true in Laravel

I am trying to query our database to see if users can log in based on whether the organisation they belong to have logins enabled.
LoginController.php
protected function redirectTo()
{
$user = Auth::user()->id;
$userOrg = UserOrganization::where('user_id', $user)->first();
$org = Organization::where('id', $userOrg->org_id)->first();
if ($org->allow_org_login == 0) {
return '/login';
} else {
if(Auth::user()->has_changed_temp_password == false)
{
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/user/password/change';
} else {
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/overview';
}
}
}
trying to log in as a user belonging to an organisation with allow_org_login = 0 should redirect to the '/login' page, but instead it either logs the user in or prompts for a password change for a new user.
What am I doing wrong?
Edit: Debug contents of $org (allow_org_login on the bottom line)
since there is many to many relation between user and organization.
i suppose this relation is defined in User & Organization as in documentation:
https://laravel.com/docs/7.x/eloquent-relationships#many-to-many
considering that:
user may have more than an organization, and if any of the organization allowed log_in the user should login to your system
$user = Auth::user();
$userOranization=$user->organizations()->get();
$allowUserToLogin=false;
if($userOranization->where('allow_org_login',1)->first()!=null)
$allowUserToLogin=true;
and then:
if ($allowUserToLogin == 0) {
return '/login';
} else { ....
for redirectTo() method it will only fire when we using POST method for login.
inside you redirectTo() method your check condition and then you return '/login';
which it will redirectTo login page. but this time you already login then on login it will check if user login then it redirectTo url that we config on LoginController and protected $redirectTo; it will not call redirectTo() method. cuz this time we use redirect using GET method not POST.
if you want to put validate on redirectTo() method you can try below code:
protected function redirectTo()
{
$user = Auth::user()->id;
$userOrg = UserOrganization::where('user_id', $user)->first();
$org = Organization::where('id', $userOrg->org_id)->first();
if ($org->allow_org_login == 0) {
Auth::logout(); // logout user before redirect
return '/login';
} else {
if(Auth::user()->has_changed_temp_password == false)
{
// depend on you choice need to logout or not
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/user/password/change';
} else {
// depend on you choice need to logout or not
DB::table('users')->where('id', $user)->update(['last_login' => Carbon::now()]);
DB::table('users')->where('id', $user)->increment('total_logins');
return '/overview';
}
}
}
but for my option i will create new middleware for handle this.

How to stay logged in using cookie in Laravel for manual login system?

Here is my code for login check.how can i put cookie value to stay logged in for specific time.
/*--------------- Check Login -----------------*/
public function checkLogin(Request $request){
$email=$request->email;
$password=md5($request->password);
$remember_me = $request->has('remember_me') ? true : false;
$result=DB::table('admins')->where('email_address',$email)->where('password',$password)->where('access_label',3)->where('activation_status',1)->first();
if($result){
Session::put('frontend_name', $result->admin_name);
Session::put('frontend_id', $result->admin_id);
Session::put('frontend_label',$result->access_label);
return Redirect::to('/');
}else {
Session::put('exception', 'Invalid Login Detail...!!!');
return Redirect::to('frontend-login');
}
}

Role user laravel

I use this code in my controller LOGIN and they are role type in my database: $users->isAdmin() $users->isOwner() $users->isMember()
public function dologin(Request $request){
$users = new Users;
$email = $request->input('u_email');
$password = $users->setPasswordAttribute($request->input('pwd1'));
//get user id from email
$user_id = $users->get_user_from_email($email);
foreach($user_id as $u){
$u_type = $u->u_type;
}
// Check validation
if (auth()->attempt(['u_email' => $email, 'password' => $password] )){
if($users->isAdmin() == $u_type){
return redirect('admin');
}
if($users->isOwner() == $u_type){
}
if($users->isMember() == $u_type){
}
}else{
}
}
Code in Users Model
public function isAdmin(){
return 0 ;
}
public function isOwner(){
return 1 ;
}
public function isMember(){
return 2;
}
My question:
-how to store role in session for logged in dashboard?
-how to declare in controller this role
Thanks you for all help
Note: the role type are integer 0, 1 and 2. I don't use enum type in my database for this role but integer
To use session in pages, make sure at the start of the page you have session_start(); (before any HTML tag).
After that, when he is logging in and everything is allright set $_SESSION["u_type"]=$u_type; and you can refer to it until you destroy your session.
To check in dashboard if he is admin, owner or member just check
//don't forget session_start(); at the begging of your file
if($_SESSION["u_type"]==0)
//admin
else if($_SESSION["u_type"]==1)
//owner
else if($_SESSION["u_type"]==2)
//member

how to get back to own profile after searching for an invalid username in the URL

I am new to laravel.I have a controller called userController to mangae user in my application.Here i have a user authentication and profile system.It will send the user to its own profile after login.Sometimes user may wish to search for a random username or id field in the url to search for a user.If desired user is found ,their profile info will be shown in the profile section.But if no user is found i want my application to get the current logged in user and show his/her info instead.How i can do that?
if my user name is 'zim' i can write the url mydomain/user/zim ,it will get my profile,But if i search an invalid name say 'zi' mydomain/user/zi , i want my application to return mydomain/user/zim again
All i can manage here is to show a flash message if no user is found.Can't figure out how to retrieve the current logged user.Tried to use the Request class but seems not working
loginUser function():
public function loginUser(Request $request){
$data = $request->all();
$rules = array(
'name' => 'required',
'password'=>'required'
);
// Create a new validator instance.
$validator = Validator::make($data, $rules);
if($validator->fails()){
$errors=$validator->messages();
return redirect()->back()->withErrors($validator);
}else{
if(Auth::attempt(['name'=>$request['name'],'password'=>$request['password']])){
return redirect()->route('user.show',[$request['name']]);
}else{
return redirect()->back()->with('data', 'wrong username or password');
}
}
}
show() method in userController:
public function show($user,Request $request) // tried with Request but failed
{
//
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if($info){
return View::make('user.show')->with('user',$info);
}else{
session()->flash('message','no user');
return View::make('user.show');
}
}
You just need to change your show method slightly.
public function show($user,Request $request)
{
$indicator=is_numeric($user)?'id':'name';
$info=userModel::where($indicator,'=',$user)->get()->first();
if(empty($info)){
return View::make('user.show')->with('user',$info);
}else{
session()->flash('message','no user but here is your info :)');
return View::make('user.show')->with('user', Auth::user());
}
}
Edited for better logic.
public function show($username)
{
$info = userModel::where(username, $username)->get()->first();
if($info != null){
return View::make('user.show')->with('user', $info);
}
else{
session()->flash('message','No user found! But here is your info!');
return View::make('user.show')->with('user',Auth::user());
}
}
Here is a much simplified option. (Always allow the URL to collect only one type instead of checking if its id or username)

Set the active status of a user in the credentials and still return an activation message in Laravel 5.1

I wanted to find out how I would do as requested in the subject line, as the code below works fine but the user is logged in before checking the $user->Activated status. Here is some code to illustrate:
AuthController
public function authenticated(Request $request, User $user)
{
if ($user->Activated) {
return redirect()->intended($this->redirectPath());
} else {
Auth::logout();
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'activated' => 'You need to activate your account to login'
]);
}
}
Preferably I would like to do the following:
AuthController
public function getCredentials(Request $request)
{
$credentials = $request->only($this->loginUsername(), 'password');
return array_add($credentials, 'Activated', '1');
}
But then the only message that gets returned is "These credentials do not match our records.", instead of "You need to activate your account to login". Also how would I update a LoginStatusId once the user is logged in, currently I do it like this:
AuthController
public function authenticated(Request $request, User $user)
{
if ($user->Activated) {
$user->LoginStatusId = 1;
$user->save();
return redirect()->intended($this->redirectPath());
} else {
Auth::logout();
return redirect($this->loginPath())
->withInput($request->only('email', 'remember'))
->withErrors([
'activated' => 'You need to activate your account to login'
]);
}
}
Is there a better place to set the $user->LoginStatusId once they login, or is this the best place to put it?
Open this file vendor\laravel\framework\src\Illuminate\Foundation\Auth\AuthenticatesUsers.php
Add this block of code inside postLogin
// If activated is equal to 1, user allowed to login or throw an credential mismatch error
$userData = User::select('activated')->where('email', $request['email'])->first();
if ($userData->activated == 1) {
$request['activated'] = $activated;
}
$credentials = $this->getCredentials($request); //add these code before this line
And add 'activated' to getCredentials method. It will look like this:
protected function getCredentials(Request $request)
{
return $request->only($this->loginUsername(), 'password', 'activated');
}
You can check user login status anywhere just using this Auth::user(). No need to store login status by yourself. As example in any controller you can write this:
if(Auth::user()){
// do this;
}else{
// do that;
}

Categories