SPDCA: Cookies. For the longest time I've fought with browser cookies.
(Browser cookies are small, named variables passed between a web server and a web browser. They are what allow servers to maintain stateful information about you (Are you logged in? What is in your shopping cart? etc.) over the course of your browsing session. They often looked upon as the least sophisticated part of the HTTP protocol specification.)
In all of my previous projects, I have simply tried to get the cookies "right," and then walk away and never touch it again. In v2, they were a goddamn mess. Not only was I passing back and forth your username (something that's easy to guess and/or forge), I was also passing back and forth your plaintext, unencrypted password (something that is notoriously easy to spot if you were, say, listening in on a coffee shop wireless, etc.). Even worse: upon every page access I tried to "update" the cookie so its expiration time would be pushed further out. Each time I did so, I told the server to re-send your password in order to update the timestamp. It's probably for the best that I shut that baby down.
For v3, I decided I would try to address the problem. PHP (the programming language I designed idkfa in) has built-in session tracking functionality that takes care of things like encryption, session creation / breakdown, complex data types stored within the session, and session validation.
Unfortunately that decision, up until now, has caused my idkfa logins to last around 24 minutes unless you were a) a user actively accessing the site, or b) sitting on auto-update.
This is for the following reasons:
-
The session_set_cookie_params and session_cache_expire functions both take time values to determine how long a cookie should be issued for, and how long that cookie should be in the system's cache. The former takes its time value in seconds. The second takes its time value in minutes. The documentation reflects this poorly.
-
The session_start function does not update the timestamp on a cookie (that is, doesn't tell your browser to move its expiration window further upon page access). It just builds the session in memory (if the session exists), but nothing else. I had assumed otherwise, and without discovering session_set_cookie_param, I wasn't setting any timestamp at all (leaving it up to the web browser to clear the cookie entirely when it shut down).
-
There's a chicken-and-the-egg problem when it comes to maintaining "who is online?" records in a database. You can tell a page to start a session, but you can't reliably ask if the session's cookie was "set" until a page-load later. So how do you say "this is when somebody logged in?" Well... I haven't quite figured that out yet. As of now, I still make a few bad assumptions, but it works out in 90% of the cases. Where it breaks down is if a web client (say, a search engine accessing the page) doesn't accept a cookie. Because my script is always trying to set a cookie, and then maintain its "online" status, I end up generating hundreds of "online" records for a single user. (Somebody was doing this last night, which is why I was looking at this in the first place).
-
Finally, even though I figured out the cookie expiration stuff, I was still having problems keeping my sessions from expiring. Turns out, it has a lot to do with how idkfa is hosted. By default, my hosting service stores all of its session data in a single directory. PHP, to save time, only "expires" session data after a random period (usually shortly after when the time the session was to expire at the time of session creation), where if the "dice" are rolled a certain way, PHP performs its "garbage collection" routine, and removes old session data. The problem with this, though, is PHP doesn't care about which user, or which website, or really about anything when it comes to kicking off its garbage collection. Here's the kicker: if any PHP instance thinks it needs to garbage collect, it can destroy any cookies in its session storage directory. This means that even if I was setting my session lifetimes far, far into the future, anybody who set theirs to the defaults (~24 minutes) had the potential to destroy my sessions along with theirs.
When I woke up this morning I was surprised to see myself still logged in to idkfa. It's been a while. But I think I've got it "correct" now, but I'm still watching it.