Trigger function after session timeout or expire in laravel - session

Hello i'm kinda new to laravel and i have a question concerning authentication. I have the following function in my authentication controller:
public function signout()
{
// set logged in status to zero in database
$l = Login::where('user_id', Session::get('user')->user_id)
->where('logged_in', 1)->first();
$l->logged_in = 0;
if ($l->save())
{
// log user out
Auth::logout();
// Forget user session data
Session::forget('user');
// redirect user to login page
return Redirect::to('/account/signin');
}
}
Now in my session config, i have set sessions to expire after 60mins after which the user will obviously be logged out of the system. However that will occur without my other functions executing like setting user logged in status to zero in database or forgetting the user session array. Is there a way i can trigger those functions to execute after login session expire? Thank you in advance.
Update: I've been looking around again ever since i got a down vote for my question to see if there was already a solution to this, from reading the docs i got excited when i came to the "Events" section because i thought i had found a solution however i found out later on that there was no such thing as a "Session::expire" event in laravel, neither is there a function to check whether another user is logged in or not.

Your whole premise is wrong: sessions should have an expiry timestamp that's set when user logs in, and updated on every request if you want to have something like "session times out after 1h of inactivity".
Then you can basically:
Check if session is still valid when user performs a request, by checking the timestamp
Delete expired sessions using a scheduled task, so you keep things clean and tidy in the background
Anyway, if for some reason you end up needing to trigger some actions to happen when a user signs out Laravel actually has an Event that's triggered on user logout: 'auth.logout'

Related

Only one User using entire web application at a time - Spring boot

In spring boot application only one user should be using the certain page at a time (let's call it home.jsp). Another users should be redirected to different page(let's call it another_home.jsp) if they appear when accessing that same url. User doesn't login and just uses the application as it is. Any policy can be used for home.jsp could be first-come-first-serve or any other.
If more than one users are using application at a time only one user should be using home.html and all rest of the others should be using another_home.jsp.
As no login is needed in the application I believe I need anonymous sessions. Also, session needs to be expired after some time of inactivity. I've searched spring security but couldn't find anything.
I think that you don't even need spring security. Simple http session will work too. As far as I can see you just want to allocate the stream to one user and for that you need first user's session id which you can compare against whenever the requests come again. So store session id and expire after some timeout with some Time object or Date object.
In properties
server.servlet.session.timeout = 600 // 10 minutes
Something like this
private String currSessionId = null;
private Date lastDate = new Date();
private Integer TIMEOUT = 600000; // 10 minutes
public String loadHomePage(Model model) {
if(currSessionId!=null && new Date().getTime()- lastDate.getTime()>TIMEOUT){
currSessionId = null;
}
if(currSessionId==null){
currSessionId = session.getId();
lastDate = new Date();
return "home";
}else{
if(session.getId().equals(currSessionId)){
return "home";
}else{
return "another_home";
}
}
}
This is as simple as it gets when you don't have logged in users to manage and also don't need to remember previous state where user left off. Let me know if it helps.
You need to create a serverside state that is either empty or stores the identifier of the visitor that is currently claiming /home.jsp.
This could be a field on a singleton Bean, or an entity in the database.
It has to expire automatically, or it will prevent new visitors forever to make a claim.
As long as the state is empty, the first visitors identifier will be stored in this state.
And from that moment on, you will redirect all other visitors to another_home.jsp
So the Controllers Code would be something like this
if(visitorHoldsTheClaim()) {
return "home.jsp"
} else if (noClaimActive()) {
createClaimForVisitor();
return "home.jsp"
} else {
return "redirect:/another_home.jsp"
}
Depending on your implementation, these methods will do different things.
I'd usually recommend against serverside session state (more about this in Roy Fieldings Dissertation),
but for your use case, you need a way to identify a visitor over many requests.
A session would certainly be a very simple way to achieve this.
You can at least minimize session usage by only creating one session at a time - the one for the visitor that holds the claim.
In this case you'd never have more than one open session, and the visitor that owns the session is the visitor that holds the claim.
So in this case, the implementation would be be something like this:
if(currentUserHasASession()) { // checks if the current user has a session, but !!!does not create a new session if it does not exist!!! careful, HttpServletRequest.getSession(true) would create it!
return "home.jsp"
} else if (serverHasNoSessions()) { // https://stackoverflow.com/questions/49539076/how-can-i-get-a-list-of-all-sessions-in-spring
createSessionForUser(); // HttpServletRequest.getSession(true)
return "home.jsp"
} else {
return "redirect:/another_home.jsp"
}
Keep in mind that this only works if you do not create Sessions in another place.
So you have to configure Spring Boot/Spring Security to not create Sessions. How to make spring boot never issue session cookie?
Also keep concurrency in mind. For example, if you had only one server instance, you could put this code into a synchronized method to avoid two visitors creating a claim at the same time.
So... first of all, this sounds like a bad idea. I would be curious why you would need such an unusual behavior. There might be more sensible approaches for it.
Like Gregor said, the redirect code part is rather straightforward:
if(pageLock.getUser() == null) {
pageLock.setUser(user);
}
if(user.equals(pageLock.getUser())) {
return "home.jsp"
} else {
return "redirect:/another_home.jsp"
}
What is actually more tricky is the part when "expiring" the lock. It's likely the user will simply close the browser and not click on "logout" (or whatever), leaving the lock forever. On the other extreme, the user might be gone for a lunch break but its browser still has the page open for hours.
So that's the first thing you wanna add: some keep-alive mechanism on the page, regularly prolonging the lock, and some expiration checker, releasing the lock if nothing was received for a while.
...but like I said in the beginning, the whole thing sounds fishy.

Logout Session with sess_destroy() not working

Currently I have an issue with CodeIgniter and sess_destroy, I want to have a user to have only one session, so I'm validating if the user have a previous session and he/she want to continue on this second session, we call an exit function to kill the first session so the user can keep the second session he/she starts.
This is my function to destroy the session:
public function salteya(){
$this->session->set_userdata(array());
$this->session->sess_destroy();
log_message('error', "salteya");
//redirect(base_url("Administrador/gotohome"));
}
The behavior is that when the user starts the second session and I try to destroy the first session need to refresh two times the pages or change the page two times to destroy the session.
Anyone had this issue before? Undecided
Best regards,
try this
public function salteya(){
$this->session->unset_userdata();
$this->session->sess_destroy();
log_message('error', "salteya");
//redirect(base_url("Administrador/gotohome"));
}

Sentinel Package: Getting all logged in Users

I'm using Sentinel in Laravel for user management. I logged in 2 users and I try to get a list of all logged in users but this only returns the very last user to log in.
The code below is one of my attempts. I know im doing it wrong pls help.
public function getLoggedInUsers(Request $request,User $user)
{
$loggedinUser ="";
foreach($user as $loggedinUser){
return Sentinel::getUser($loggedinUser);
}
}
It returns only the last logged in User instead of a list of all logged in users
The return key will exit the function getLoggedInUsers() the first time it is hit. This means your foreach loop is only executing one time and immediately returning the first user. Additionally, your $user variable is a single user, meaning there is nothing to loop over, it will only execute one time regardless.
I could not find in the documentation if Sentinel has a function for getting all active users.
I'm not sure if Sentinel supports it, but if the User sessions can be saved to the database instead of the filesystem, then you should be able to check to the sessions table for active users. In basic Laravel authentication, you can change where the user sessions are stored. Sentinel might have something similar or might use config/session.php as well. (https://laravel.com/docs/5.8/session)

keeping laravel session variable till user logs out

I have a simple authentications for user,In UserController I have a fuction called postLogin().
public function postLogin()
{
if(Auth::user()->attempt($credentials))
{
return Redirect::intended('desk')->with('stream',"SomeData");;
}
}
with above code I am able to log in successfullt with the "SomeData" variable which I am retrieving it by
<?php
$class = Session::get('stream');
var_dump($class);
?>
First time when it goes to "/desk" url it dumps the value perfectly fine that is "SomeData" but once I refresh the page it resets the session and the value turns to null.
How do I keep this value till the user logs out.
From the laravel official documentation :
Flash Data
Sometimes you may wish to store items in the session only for the next
request. You may do so using the flash method. Data stored in the
session using this method will only be available during the subsequent
HTTP request, and then will be deleted. Flash data is primarily useful
for short-lived status messages:
$request->session()->flash('status', 'Task was successful!');
If you need to keep your flash data around for even more requests, you
may use the reflash method, which will keep all of the flash data
around for an additional request. If you only need to keep specific
flash data around, you may use the keep method:
$request->session()->reflash();
$request->session()->keep(['username', 'email']);

Most efficient way of authorizing users over different pages on my site?

I have only ever made single page webapps in the past; with these, as soon as a user connected, I would read the password hash stored in their cookies and match it to the value stored in my database to determine if the user was already logged in.
I am now wanting to make a site with multiple web pages though, and I have just realized that it would required querying the database every time a user goes to a new page; this seems extremely inefficient to me. Is there any better way to maintain an ongoing session with a client without straining my database/server in the process?
Take a look at using a session object Eg HttpContext.Session["UserAuth"] = true;
When you authenticate the user on your first page Eg Login, you can then create a session like in the example above. Then once you redirect to the next page, just check to see if the session does indeed exists and is valid.
Checking session:
if(HttpContext.Session["UserAuth"] != null)
{
if(HttpContxt.Session["UserAuth"].toString() == "true")
{
//Session is valid and user is logged in.
}
else{
//Session is invalid and user is not logged in.
}
}
So each page you want to check if the user is valid you can do the above check. As long as you have created the session on the first page at time of database authentication.
Please note the above code is just to give you an idea of how you can do this.
"UserAuth" is simply a the name you give to the Session that you are storing. It can be absolutely anything. The value you are storing in the Session in this case is 'true'.
So when you retrieve the value of the Session you simply get 'true', meaning the user is logged in.
When you log the user out for example you can change the value of the session "UserAuth" to false in the same manner in which you originally created it.
Eg
HttpContext.Session["UserAuth"] = false;

Resources