![]() |
Session serialized data... kinda? Dont understand the format - Printable Version +- CodeIgniter Forums (https://forum.codeigniter.com) +-- Forum: Using CodeIgniter (https://forum.codeigniter.com/forumdisplay.php?fid=5) +--- Forum: General Help (https://forum.codeigniter.com/forumdisplay.php?fid=24) +--- Thread: Session serialized data... kinda? Dont understand the format (/showthread.php?tid=62739) |
RE: Session serialized data... kinda? Dont understand the format - jLinux - 08-26-2015 (08-26-2015, 08:55 AM)mwhitney Wrote: It sounds like you've gotten to a point where things are more complicated than they should be. Actually my issues a little different. Let me explain the end goal here. So, this app will be able to be used via API, CLI or HTTP, and it can be setup so people can use the login more than once (EG: an API account "Service account", or something). So I need it so someone can login and see all the active sessions associated to their account, as well as whats going on with them, live. I have it setup so CI will delete the old session when the session is regenerated, so there wont be a ton of old sessions polluting the sessions table. I have a MY_Session: ![]() ![]() I created a MY_Session_database_driver::write(), which will execute parent::write(), then execute Accounts_model::assoc_session($_SESSION['account_id'], $session_id); to set the 'account_id' column in the 'ci_sessions' table to the current account ID. I believe the problem im running into, is when the session is regenerated, it doesnt right away create a row in the ci_sessions table... I tried to put some code inside the MY_Session: ![]() I put a lot of logging into the logs, and heres the logs and some comments on what they mean... Quote:1) DEBUG - 2015-08-26 10:38:09 --> SESSION MY_Session: So basically, when sess_regenerate is ran, it will change the session ID, but it doesnt actually write the new session ID record in the ci_sessions table yet.. So my question is, how can I have it do that when the session is regenerated? I know I COULD have MY_Session: ![]() I know I could try to set the CI_Session_database_driver::$_row_exists to TRUE, so that CI_Session_database_driver::write() will update the row, instead of create it, but right when CI_Session_database_driver::write() is executed, it will reset it to FALSE. Basically, all I really need, is for the session to be written to the database, right as its regenerated, (but then CI_Session_database_driver::write() will throw a fit because its trying to create a row that already exists) Is there a way to have CI_Session_database_driver::write() execute when the session is regenerated? I know the CI_Session::_construct() uses session_set_save_handler() to set the handler, which will have write() eventually executed, I just need to have it done earlier, somehow If anywhere between lines #3 and #6, I could have MY_Session_database_driver::write() execute, that would save the day. Hope I made this clear enough... and thank you for the help! P.S. I know all the methods/properties I referenced arent static, I just referenced them like that to make it easier to understand ![]() RE: Session serialized data... kinda? Dont understand the format - mwhitney - 08-26-2015 I think I understand most of what you're trying to do, I just don't understand the need to store the account_id in the session table. In my opinion, it would be easier to store the account_id in the session itself (not a new column in the session table) and create another table which would store the account_id and session_id values (with as many session_id entries per account_id as you need) so you could lookup the sessions associated with the account without having to get into the session data itself (except, of course, for getting the account_id from the current session). Honestly, every time I think of some idea for modifying the session table, I eventually run into something that requires replacing the write() method on the driver or something even more drastic. To address some specific items in your text above: Quote:I have a MY_Session:Confusedess_regenerate() function, which just stores the "old" session in a public property, executes parent:Confusedess_regenerate(), then stores the "new" session in a public property. Then whenever the Account_model finally loads, it will check if the $new and $old are both populated, if so, then that means the session was regenerated, so take all the "activity" (NOT in the ci_sessions table) and change the session ID to the $new session id, thus allowing the user to see the activity that was going on for the same Login, even though it was a different session. I think something just clicked for me here, but I'm not going to go back and change what I wrote above. It seems to me that the "activity" should be associated with the account, rather than the session. The relationships in the database should tie to the activities to the account, not to the session. It's best to leave the session alone to do its work and leave it out of your database relationships (and that also frees you up to use a different session driver). If you want to record the session_id used for an activity as some sort of artifact for logging or whatever, that's your prerogative. If you want that session_id to reflect the chain of regenerated session_id values, then create a new table with an auto ID value and a session_id value, record the auto ID in your activity table and update the new table's session_id when the session is regenerated. Then you just join the activity table to the new table and read the session_id from the new table, but the activities themselves are still related to the account by the account_id, and you display activities based on the account_id, not the session_id. RE: Session serialized data... kinda? Dont understand the format - jLinux - 08-26-2015 (08-26-2015, 12:05 PM)mwhitney Wrote: I think I understand most of what you're trying to do, I just don't understand the need to store the account_id in the session table. In my opinion, it would be easier to store the account_id in the session itself (not a new column in the session table) and create another table which would store the account_id and session_id values (with as many session_id entries per account_id as you need) so you could lookup the sessions associated with the account without having to get into the session data itself (except, of course, for getting the account_id from the current session). Thats what I was doing originally, I believe Narf said that was over-complicating it, and it would be best to just create a new column in the ci_sessions table. I do think its easier this way, because then to look for any active sessions for a given account, I can just select from the ci_sessions table where the account_id = $id. The account_id is ALSO stored in the session data, I just cant select rows from the table based on a value of a variable in the session data though. (08-26-2015, 12:05 PM)mwhitney Wrote: To address some specific items in your text above: The activity in the accounts_activity table is all associated to the account_id, it also however has a session_id column. When any activity takes place, it will create a new record in the account_activity table, with the account_id = $id and session_id = $current_session, then whenever the sess_regenerate() takes place, it will UPDATE account_activity SET session_id = $new_id WHERE session_id = $old_id, allowing the user to see everything that took place for that single login, even though it had multiple regenerated sessions. (08-26-2015, 12:05 PM)mwhitney Wrote: If you want to record the session_id used for an activity as some sort of artifact for logging or whatever, that's your prerogative. If you want that session_id to reflect the chain of regenerated session_id values, then create a new table with an auto ID value and a session_id value, record the auto ID in your activity table and update the new table's session_id when the session is regenerated. Then you just join the activity table to the new table and read the session_id from the new table, but the activities themselves are still related to the account by the account_id, and you display activities based on the account_id, not the session_id. That sounds like it might work.. Ill give it a shot! Thanks RE: Session serialized data... kinda? Dont understand the format - jLinux - 08-26-2015 Question... Is the CI_Session_database_driver::destroy() called when the session is regenerated, as well as logout? I took your advice, and created a table, account_sessions_assoc, that has a unique automatically generated ID, which is the main point of reference, as well as account_id and session_id, when MY_Session_database_driver::write() is called, it will execute parent::write(), then it will execute another method, Accounts_model::account_session_assoc(), that checks if the old session ID is in the account_sessions_assoc table, if so, update the account_sessions_assoc.session_id to the new $session_id, if not, create a new record with the $account_id and the $session_id. I created a MY_Session_database_driver::destroy() which just executes parent::destroy(), then executes a newly created MY_Session_database_driver::_assoc_gc(), which will delete any records in the account_sessions_assoc table if the current account_sessions_assoc.session_id is NOT in the ci_sessions table (This method is also executed by MY_Session_database_driver::gc(), which just executes parent::gc() then _assoc_gc()) The problem im running into, is records are getting deleted out of the account_sessions_assoc table, when sessions are still in ci_sessions, and after viewing some logs, it looks like the MY_Session_database_driver::destroy() method is being called when the MY_Session: ![]() If im right, and the destroy() is being called when the session is regenerated (probably because sess_regenerate_destroy = TRUE), then I need to somehow let the MY_Session_database_driver::_assoc_gc() method know that the session is being regenerated, and not to delete it. Thank you for the suggestion about creating a new table for associations, that was what I originally did, and should have stuck with that, definitely works better. Now just got this one last issue to take care of! Thank you for the help! Update: I added a column, account_sessions_assoc.regens, which will start at 0, and +1 for every time a record is updated, I removed the reference to self::assoc_gc() from MY_Session_database_driver::destroy(), and the regens started climbing.. 1.. 2.. 3.. etc. Then I re-added the reference in destroy() to self::assoc_gc(), and the new records were all being added to the account_sessions_assoc table, new ID's, session ID's and regens are staying at 0. So its definitive that destroy() is being called when sessions are regenerated. Since MY_Session_database_driver::write() is what does all of the inserts/updates in account_sessions_assoc, I believe what im running into is ironically the EXACT same issue I had before I took your advice, which now, is... 1) MY_Session: ![]() 2) Then MY_Session_database_driver::destroy() gets called, which deletes the session_id from ci_sessions 3) MY_Session_database_driver::destroy() calls self::assoc_gc(), which will delete the record from account_sessions_assoc, since MY_Session_database_driver::write() has not been called to quickly create the new record. If I can have MY_Session_database_driver::destroy() realize its being called after MY_Session: ![]() I tried doing this, but it doesnt seem to work: PHP Code: <?php ![]() P.S. Sorry for the overwhelming amount of info.. Im just trying to be as precise about whats happening as I can be. I think its also making the situation seem more complicated than it really is, which I hate doing. RE: Session serialized data... kinda? Dont understand the format - jLinux - 08-27-2015 I ended up using debug_backtrace() to see which function was calling it... Seems to work.. PHP Code: <?php If theres any CI best practices that I violated, lmk ;-) |