Laravel : Check if another user is currently logged in - php

I'm speaking about a simple laravel's 4.2 web site with authentication system.
I am user A (super-user), and I want to see if user B or/and user C (and all other users) are logged in. Is there any built in function (something with Auth class) to do this ?

You can't say for sure if a user B/C is logged in. But you can guess if a user is logged in. If you remember the last action of user B/C and you know the timeout until a user gets logged out automatically this would give you an estimate value if the user is still logged in or not.
Add a migration for your users table and add a new field to your table
$table->timestamp('last_activity')->nullable();
Add a before filter
App::before(function ($request) {
if (Auth::user()) {
$user = Auth::user();
$now = new DateTime();
$user->last_activity = $now->getTimestamp();
$user->save();
}
});
Now you can check when the last action of user B/C was and if this is within the auto logout time it is possible that the user is still logged in. If not the user is definitely logged out.
In case you want to log users activity there is a package Regulus343/ActivityLog.

It's easy but you can only check one person at time which means it's not possible to use complex conditions for example count all logged in users.
If you want to check if a user other than you is logged in, use a helper function like this.
<?php
// Helper.php
public function isLoggedIn($user_id)
{
if(Auth::check())
{
return $user_id == Auth::user()->id;
}
}
?>

Related

Laravel 5.6: Force logout remember me login

I have a custom login controller in my app, which prevents multiple sessions per user. It logs out the user if they log in from another device/browser:
public function authenticated(Request $request, $user) {
$previous_session = $user->session_id;
if ($previous_session) {
session()->getHandler()->destroy($previous_session);
}
auth()->user()->session_id = session()->getId();
auth()->user()->save();
return redirect(session()->pull('from', $this->redirectTo));
}
Regardless of the session driver, this code looks for a session_id on users table and destroys the session associated with it.
But this doesn't work if the user logged in with remember me checkbox enabled. User stays logged in with previous device/browser. How can I tell laravel to forget this remember me after the second login? Thanks.
You have to invalidate or cycle the remember_token in the users database table.
This happens automatically when you call Auth::logout().
The remember_token can also be invalidated manually similiar to how Laravel handles it:
protected function cycleRememberToken(AuthenticatableContract $user)
{
$user->setRememberToken($token = Str::random(60));
$this->provider->updateRememberToken($user, $token);
}
Source: laravel/framework/src/Illuminate/Auth/SessionGuard.php

laravel event listener for session expire, as no logout event listener called on session expiry

the scenario is simple: i want a single user to be logged in from only one device at a given time. using laravel framework version 5.2
here is my work so far to achieve this, using event listeners:
i set a is_logged_in flag in users table which is ON when user logs in. and based it its ON status it will reject all the subsequent request of log in from same user.
i used login attempt, login and logout events to achieve this:
on login attempt listener the following code is executed. it will check if the user is already logged in then a flag logged is set in session.
$user = User::select('is_logged_in')->where('email', $event->credentials['email'])->first();
if($user->is_logged_in == 1){
Session::put('logged', 'Yes');
}else{
Session::put('logged', 'No');
}
now at login event, the session flag logged is checked, if its set then user is forcefully logout, maintaining the remember_token (which is changed on logout)
if(session('logged') == "Yes"){
$previous_remember_token = $event->user->remember_token;
$previous_usesr_id = $event->user->id;
Auth::logout();
$user = User::find($previous_usesr_id);
$user->remember_token = $previous_remember_token;
$user->save();
}else{
$event->user->is_logged_in = 1;
$event->user->save();
}
and in logout even i used following code to reset user database flag of is_logged_in:
if(session('logged') != "Yes"){
$event->user->is_logged_in = 0;
$event->user->save();
}
now here are the issues im facing:
When session expires, logout even is not executed, how can i execute my logout event code on session expire? is there any session:expire event listener present in laravel?
1.1 This also leads to another question what how laravel monitor session time, and where it saves it? how and when laravel framework make the session as expired?
i also want to execute the logout code when the user close the tab or browser, which is really hard but i think may be some ajax function updating the users table column after a certain interval and write a cron job to check the interval and switch OFF the flag in DB, is there any better way to do this, please guide?
Create your own session driver handler in laravel and execute the code you want in "destroy" and "gc" events of your handler.
You can simple copy the default DatabaseSessionHandler code from
Illuminate/Session/DatabaseSessionHandler.php
and name it lets say CustomeSessionHandler.php.
make sure to register the new handler in AppServiceProvider
public function boot()
{
Session::extend('custom', function ($app) {
$connection = $app['config']['session.connection'];
$table = $app['config']['session.table'];
$lifetime = $app['config']['session.lifetime'];
$connection = $app['db']->connection($connection);
return new CustomSessionHandler($connection, $table, $lifetime, $app);
});
}
and in your .env or your config/session.php
use the new driver
SESSION_DRIVER=custom

Laravel pass value both as admin and normal user

I have a site where an admin can register themselves. Currently there is only one admin so the functions below works for passing the value:
public function getAllVideos()
{
$videos = Video::all();
$price = DB::table('donor')->sum('amount_donated');
$goal = auth()->user()->goal;
return view('adminmanagement', compact('videos', 'price', 'goal'));
}
public function changeGoal(Request $data)
{
auth()->user()->update([
'goal' => $data->input('newGoal')
]);
return redirect('/home');
}
And if I need to just pass it to a view where a normal user can see,
do I do the following?
public function getAllVideos()
{
$videos = Video::all();
$price = DB::table('donor')->sum('amount_donated');
User::first()->goal;
return view('adminmanagement', compact('videos', 'price', 'goal'));
}
public function changeGoal(Request $data)
{
auth()->user()->update([
'goal' => $data->input('newGoal')
]);
return redirect('/normalview');
}
But what if there are more than one registered users (admin) in the system. Would it still be fine as only one admin is logged in at a time? Or does the code need to change?
EDIT:
I have registration only for admins (which are 'user'), the normal users ( which are 'donors' in my case) don't have any registration/logging needed. So my main purpose is to be able to pass that $goal value to two different pages. One accessbile to admin(let's say a registered and logged in admin named jon), and other accessible to the normal user. so my current code 'User::first()->goal;' should do the trick, right? but, will it be fine if lets say, another admin named jim registers and logs in. So now the admin that is logged in is jim, not jon will it still display the $goal value in the admin's view page(accessed by jim) and normal user's view page(accessed by a normal/random person)?
From your other question you said that there's only one user and it's an admin. In that case you could replace the auth()->user() with User::first(). But if you have more than one admin or users, you need to specify the user using User::find(1) with the user id. Every user has a goal field and i assume you want to fetch only the goal from the admin user with the actual value. If so you can do this.
Replace
$goal = auth()->user()->goal;
With
$goal = User::find(1)->goal;
Make sure to use the user id of the user with the goal value.
retrieving user via auth()->user() Or Auth::user()(I prefer the second way) only return the current logged user.
If you write :
Auth::user()->username it will display their own name to all user viewing this page.
No need to worry :)
However, User::first() will get the first reccord in the users table so it will always be the same user and it may be a normal user

Allow admin users to see what other user type can see/do?

I have a Laravel web application consist of 2 types of user:
customer
admin
Base on their user type , they can see, and perform different things.
Customer
When log-in as customer, my customer will see different dashboard.
Admin
When log-in as admin, I can see a list of users in a table
Example,
userA
userB
userC
more …
Goal:
I want to see what customer see when click on one of the user on the list.
I couldn’t come up the solution for that.
IMO
Will Auth::user()->type work for this scenario ?
The goal is to render the page as Auth:user()->type == ‘customer’, when the actual Auth::user()->type == ‘admin’. I'm not entirely sure if what I am trying to do is possible.
How would I do something like that in Laravel ?
You could try what I did in one of my projects - implementation is pretty simple, maybe you can make use of that as well.
There is additional action in our AuthController that allows a user to switch to other users and remembers current user ID in session:
public function switchUser($userId)
{
// disallow switched users from switching again
if (Session::get('previous_user')) App::abort(403);
$user = User::findOrFail($userId);
Session::set('previous_user', Auth::id());
Auth::login($user);
return redirect('some path');
}
Second part is customized logout function, that for switched users switches them back to their original user account instead of logging out:
public function getLogout()
{
if ($previousUser = Session::get('previous_user')) {
Session::remove('previous_user');
Auth::loginUsingId($previousUser);
return redirect('some path');
}
Auth::logout();
return redirect('some path');
}
With that logic you'll be able to switch to other users and back. You might need to add permission checking, so that only admins can do that etc., link the customers in the list to the switch URL, anyway the core of the functionality is there in the code above.

How to list currently logged users in Kohana 3 Auth Module?

I dont use any tokens.
I know that it is possible to get currently used user like this:
$user = $this->get_user();
I need function to check if any user is logged :)
I want to do something like this:
//extending Model_User:
public function is_logged()
{
//return true or false
}
//using in controller
$user = ORM::factory('user');
$user->find($this->request->param('id'))
if($user->is_logged())
{
//do_something();
}
Auth module doesnt store any information about user sessions. You must create a table like (user_id, login_time, last_update_time, user_fingerprint). Where user_fingerprint is an unique token (for exampple, sha1(user_id + user_ip + user_agent)). Update this table after login/logout. last_update_time will store timestamp for last user activity (page load, ajax call etc), and it can be used for filtering old connections by timeout.

Categories