Hi Everyone,
I'm building a REST API that will be accessed by mobile phones and a web frontend (like how Twitter does it now).
Authentication with SimpleAuth is working well, but I've run into an issue with sessions:
On login, I'm calling Auth::check() to see if a user is already logged in; however, successful logins are stored in a session, and subsequent attempts to login with another user fail, saying the user is already logged in (even if they're not).
I know I can set "expiration_time" in the config to something like one second, which works, but it's a hack. If multiple clients request login in under one second, some will fail, saying they're already logged in.
So first off, am I going about this the wrong way?
And if not, how can I only enable that session storage for the web frontend?
I'm not really sure what the issue is here.
Logins don't have anything to do with what's in the session. Whether or not someone is logged in, a login will just overwrite whatever is in the session.
SimpleAuth doesn't have any features to disable multiple logins, nor "already logged in" messages. It uses a login_hash in the user record, which means that if you log in for a second time, the first login is simply kicked out.
Or do you mean (with your reference to twitter) that you want to be able to be logged in as multiple users in the same session?
In that case you can't use SimpleAuth, you'll have to write your own driver (perhaps with SimpleAuth as the start) that supports that feature.
Thanks for the reply! No, sorry - it's difficult to explain.
So I know how all the SimpleAuth stuff works - I read every line of code in that and Auth.
What I meant by "already logged in message" is I basically have this (pseudo code):
if ( Auth::check() ) {
// Notify client "already logged in" (send response)
return;
}
$auth = Auth::instance();
if ( $auth->login($username, $password) ) {
// Send success response/message + login_hash
}
else {
// Send error
}
The Auth::check() always returns true, if the call happens within the "expiration_time" duration, which is set in session.php in config. So it does save the session, and I'm sure running $auth->login would overwrite it, but it never gets to that block, since I need to check if the user is logged in already.
Does that make more sense?
Also, the reason I know it's storing in session is I dropped this in \packages\auth\classes\auth\login\simpleauth.php around line 67 (I'm using 1.3 btw):
\Fuel\Core\Log::debug(
'SESSION/USERNAME: ' . $username . PHP_EOL .
'SESSION/LOGINHASH: ' . $login_hash
);
And you can tail -f and watch it dump the same session info every time that login controller is hit.
That's what Auth::check() is supposed to do, restore the user context. It's the only way to maintain a session.
Otherwise you would never be able to have a logged-in user, the user would be logged out again at the next request.
I think your logic is borked, in that you check for an existing session before you process the new login. If you want to swap users, just do a new login when a new username/password is posted. It will overwrite the stored session information. And do your Auth::check() after that.
[RESOLVED] (since I can't seem to change the discussion name)
So my workaround ended up being an isLoggedIn() type method that just checks for the presence of a login_hash in the database. The has is not returned (since that could be dangerous), so if a client somehow "loses" the auth token, they can just force a login refresh, overwriting the old hash.
I think this is the simplest way, without writing a custom auth driver.
I've installed a forum feature in which you can select to start a question instead of a discussion. With questions you can indicate if is was answered.