Access User session by id

Is there a way to access User Sesson by id ?
I tried several methods but none could work.
I mean something like :
return $this->find()->where([‘Sessions.User.id’ => $userId])->first();

(I use database sessions)

Check out this…
https://book.cakephp.org/3/en/development/sessions.html#accessing-the-session-object

Thank you but I already read this page but the answer is not there.
It only tells you how to get current user id.
I want to get any user id to check if he is connected or not.

You want to find out whether someone is currently on your site? That’s nearly impossible, because closing the browser doesn’t send any notice to your server. You want to find out if they’ve been on your site in the past X minutes? That’s more manageable.

As it is a private workplace site, most people log out (they have recommendations to do so).
So that solves a part of the problem.
Plus, you can check who’s online bye checking the time between login and session time but it may be time consuming.
But, the first thing would be to quickly know who is there and who you can work with.
That is why I’m looking for some simple method that could instantly list connected workers.

What’s the schema of your sessions table look like?

Oh wait, the answer seems obvious now…

First, is $this when you’re doing your find the SessionsTable? If so, then you want something like

$this->find()->where([‘Sessions.user_id’ => $userId])->first();

Note Sessions.user_id, which references a field in the sessions table, vs your original Sessions.User.id, which references a field in a join table, and probably a mis-named join (User vs Users) at that, and furthermore a join that you haven’t asked it to make.

Do note that if someone is logged in on two devices, they’ll have two sessions, and you’re only looking at the first one here.

If you’re already reading the User record for some other purpose, then the better option is probably to contain the Sessions when you do that, then you can skip this entire bit.

Thank you very much again.
session schema is cake standard.

As of cake standard session schema, sessions are not associated with users (in the way of cake associations). So there is no way to contain the session (I tried) :
$user = $this->Users->find()
->where([‘Users.id’ => $id])
->contain([‘Sessions’])
->first()
;
Or this would imply a different means of managing sessions.
Or, there is something I am missing.

Another question :
Why can’t I access Sessions->id and Sessions->expires directly from any user ?
$this->request->session()->read() only access Sessions->data.
I managed to do it but I had to write a long function to extract user_id

You can get Session data and store it in a variable like $user = $this->request->session()->read(‘Auth’); and then get the id like this my_Id= $user[‘User’][‘id’];

Assuming that you have UsersController with id, you can get Session data and store it in a variable like $user = $this->request->session()->read(‘Auth’); and then get the id like this my_Id= $user[‘User’][‘id’];

Thank you for taking time to answer.
I do not want the user.id but the session.id and associate it with user in order to access variables time (in user session) and expires in Sessions table.

Finally got around to looking at this again. Seems I’ve never really looked at the sessions table; I had assumed it had a user_id column, but that’s not the case.

Because, as I now realize, there’s no direct tie between the sessions and users tables. Sessions only have id, data and expires. If I had to guess as to why that’s the case, I’d say it’s because the user_id is technically available in the data, and sessions are generally just used to track information for the current user, not examined by other processes, so having it accessible through $this->request->session()->read() is good enough.

That would be the “easy” way to do it. It shouldn’t be that long a function, you could just unserialize the data for the relevant session(s) and read the value straight from the resulting object. (See the internals of the standard session handler if you’re not sure how to go about that.)

Another way would be to extend the standard session management to include a user_id column in the database. That’s likely to be quite a bit more work, though, and presumably potentially sets you up for a bit more pain if they ever change the internal structure of sessions; changes that Cake makes in this area might well break your code.

Thank you for thinking about it.
I am persisting in this “problem” because first I am looking for a solution and second, I’ve read several posts in various forum about managing sessions.

  • first, the best way would probably be to write my own session handler (or extend the original one) but, as you said, it could be a lot of work and what about updates ?
  • second, trying to do with what we have.
    That’s what I’ve done.
    So, for those who would like to do the same, here is a solution that work fine :
  • write a function that returns the user id, session id and the expires variable.
  • add a “connected” boolean variable in user table
  • add two fields in the user table (I named them joined_at and left_at)
  • write two functions in the user table file (I called them the same joined_at and left_at)
  • each time a user logs in, update the “connected” variable and “joined_at” with the right value.
  • update the “connected” variable and delete the corresponding session on logout.
    In fact, it works perfectly except when a user quits his browser without logging out. That is why you need to check for connected users each time users log in.

So, you need to add :

  • each time any user logs in or out, look for every “connected” variables and compare with the “left_at” variables and with the “expires” variables (in relation with session duration).
  • add a javascript that runs every minute and checks for the same variables.
  • add a javascript that runs on before unload to update user left_at and connected.

It is not perfect but quite reliable.