I'm in the initial stage of building a php/mysql backend that exposes a REST interface to a website and iphone/android/etc devices.
I'm not quite sure what is the 'standard' or 'best practices' for dealing with sessions for multiple devices that use the same account.
Here is my current thoughts on how this would work:
I would use MySQL to store sessions for now, with a sessions table like so:
id, session_id (hash), user_id (int), created (timestamp), expire (timestamp), device (enum)
When a user login via iOS app or android app, I would return a session token in the success json for future api calls to use. Same with the website making an api call.
For security purposes, I should regenerate and overwrite the session token if the user re-login, but only for the session_id for that device.
I also have an expire column that tells me the expiration of the session so that if I wish, I can create a session that can expire in two weeks and is periodically cleaned by a CRON job.
This seem like a reasonable approach to me, but there are problems if the user uses an iphone and an ipad, or multiple android devices using the same account. Anytime the user logins with one would cause the other to log out.
I noticed instagram didn't invalidate the session even if I login from another iphone.
However, I don't think I can duplicate that behavior unless I never overwrite a session token when a user re-login or keep adding session rows into my session table whenever the user logins from the iphone?
What is the standard way of handling sessions across different devices?
I would highly discourage you from using mysql to store sessions. I would suggest using redis or memcache. Redis will store the data to disk in case your server crashes. Redis also allows you to set a TTL to expire the session, which would solve #4.
If you are using rest based calls, I would suggest just adding the session to the header as a cookie and pass that back and forth. Basically emulating the way a browser would access that page. I think that would make testing easier too.
Well it seems what you are looking for is not what most would traditionally call "sessions", which is something typically limited to a single browser or client instance.
It seems you are talking more about attaching application state to the user login. In which case, I don't see why you would have a need for a separate session table/token system. You would simply use your typical client-side methods of persisting a login, and then when that logged in client contacts your API, you would return application "session" state information, regardless of what actual client instance you are talking to.
This is not to say you wouldn't want to use some sort of token exchange system to give users "fresh" tokens in a case that you wanted to purge their state after a certain period of inactivity, just that you could have multiple active tokens per login.
Related
I have ServiceSite.com (SS) and multiple GameSite.com's. All games authenticate through SS and then log in with their own personal databases. That's all done with a simple JSON API, no need to log into SS to get into a game.
I have the one goal of logging into a game and accessing the features of SS through the game, such as accessing a player's Contact List and Profile, both of which are shared between all games. While in GameSite.com/play, they'll hit a link to ServiceSite.com/contacts and get the response as if they were opening it from ServiceSite.com. I use JSON Web Tokens to manually log the user into SS, to simulate a real login to ServiceSite.com.
This works... so long as they're on the same domain. Meaning, as I'm developing a game, I'll use ServiceSite.com/tempgameurl and any call to ServiceSite.com has no problem establishing and keeping a session. But once the game gets its own domain, or if I'm working on my localhost, I cannot get it to recognize the session on subsequent requests. If I want a response, I will always have to pass the JWT token, which is not suitable for what I'm doing. The goal is to load a game, "poke" SS to create a log in, and then if a player were to visit ServiceSite.com, they would have the session as if they'd logged into ServiceSite.com's front page with their login manually.
In short, I expect that once I hit my first JWT request and make a session on ServiceSite.com from a GameSite.com, that's it, the session is made. But it seems to only actually make a session if I'm requesting from the same domain. I do see it create a session properly, filling in $_SESSION, but that data simply does not persist if the request originates from a non-ServiceSite.com URL.
Sessions and Cookies are domain dependent, it is a browser security issue. You cannot cheat this. However, there is a "trick" you can try, even though it is a bit more complex:
You need to set a cookie for each domain:
authenticate the user, emit a JWT code and create a key=>value type of record in a shared storage (database most likely). The key should be unique, the value should be JWT code and also set an expire time of 20-30 seconds.
in the response HTML you need to make the browser set cookies for the other domains. That can only be done on those domains. So you need to fool it with something like:
<img src="http://anotherDomain/setCookie.php?key=keyFromSharedStorage" style="display:none;" />
in the setCookie.php, check the shared storage and retrieve the JWT based on the $_GET['key']. Then set a cookie with that JWT.
You could pass the JWT directly, but passing a key that expires fast should be more secure. Add an image for every domain.
Instead of a cookie you can create a session on each domain. Same principle really.
Well try saving your needed data and sessions in database itself. It seems to be small amounts of data and logs.
After a game save the sessions on the database and open from whichever place you are at.
I am working on an android app that is actually gets user data from android device and then to put it on the server, like to get user name, password, email for registration purpose and then user login to access the app menu (to see list of products, search for products and to add his/her own product details in the list). So using cookies and sessions would be a good idea for my app. Cookies can be blocked by the user and sessions every time to login to access.
But as i am totally new to this concept of cookies and sessions so it would be good to ask a question here before i have to start, that which one should i use cookies or sessions ?
The user can not block cookies. Cookies are simply headers that you will send in each request.
Cookies are easier to handle on the server side. You will simply use $_SESSION["variable"] to get/set any variable for the user. It will simplify your life on the server. However, I think the main drawback will be maintainability and administration of sessions. For example, if a user logs in again on a different device and you want the first session to be invalidated. It is not very straight forward.
If you want to use sessions, you will probably save them in a table on some database. You will need to fetch the session details when you need them. This is sort of extra effort. Yet, database sessions provide some kind of administration capabilities straight away.
I prefer database sessions for what is stated above and some other reasons. However it is up to you
I am creating a RESTful API-centric web application. Once a user logs in they will receive a session id and login key that will be used for accessing their data until their session expires. The web application (and possibly the mobile applications) will call an API every page load to get user information if a session is saved in the memory. I am working on optimizing this API call as much as I can, and I wonder if it makes sense to cache this information.
Every table with user data contains a updated timestamp (triggered on every Postgres update). So I could modify the API to accept an optional cache_timestamp parameter. The API would first check to see if any of the user data's tables have been modified since that timestamp. If they have, then it would return the updated user data; if not, it would return a 304 not modified and the application would use the cache.
My question is what information is too sensitive to save in memory (using PHP sessions). Currently the information contains things like profile (name, company, etc), contact (email, phone), settings (newsletter, notifications), and payment info (plan, trial, and an customer ID that refers to Stripe).
The only thing that I think would be on the edge is payment info, but they shouldn't be able to access any data from Stripe unless my API keys are compromised.
I'm not a Security expert, but since the sessions are stored on the server, the only way for an attacker to access the data is to have gained some privileges already.
You can look at this interesting post PHP Session Fixation / Hijacking about how to secure more your sessions.
If the user's session got hijacked, then there is nothing to do, the attacker will access the data like if it was the user in question.
If the attacker can exploit a fail related to your server, then he should probably be able to read the session data (which is stored serialized in some files by default).
So, crypting the sensitive data, can prevent him from reading it raw.
My opinion is also same, Payment info should be store in the Session variable, but then you are saying it's not accessible without API key. I think you are at safe side.
I want to create a session on a server backend for Joomla PHP and a Javascript quiz module, that are used from an Android application.
Even if the Android application closes unexpectedly, that session should be available again on a subsequent load of the application.
What's the best way someone can suggest for this?
I'd suggest storing the PHP Session cookies on disk if you are going to use $_SESSION in PHP. Otherwise, you should look into cookies that you can manually set the expiry time on and keep them stored on disk in Cache/
That will store the current progress of the application in the session cookie, but without a login (or code from you) there's not that much more i can say.
To access from another browser/device you would need a login to identify the user and provide them with a valid session.
Create a user account in your database for each phone, maybe identified by the phone's udid.
Store the data in your database as the user moves through the quiz
When the user opens the app, check their udid against your database and retrieve any data that is needed for that user
I'm making a forum for learning mostly but hopefully it will have a couple of users some day.
What im wondering is should you use sessions or cookies for user authentication?
A cookie is a short piece of arbitrary data that the server sends through a header; the client stores it locally and sends it back on the next request. This mechanism can be used to maintain state from one request to the next even though HTTP itself is a stateless protocol. Cookies have two disadvantages: They offer only very limited amount of space (4 kB), and because they are sent back and forth in plain, a malicious client can fiddle with the contents before sending it back to the server, effectively making cookie data untrusted.
A session is a file on the server, identified by a unique ID which is sent back and forth between client and server so that the server can identify the client. The most popular way of sending the session ID is through the cookie mechanism, but it is also possible to pass the session ID through the URL (this is why you often see links that contain the URL parameter 'phpsessid'). This solves the two problems with cookies mentioned above: A file on the server can be as large as required, and the client cannot access the data other than through your own scripts.
Authentication is typically solved using cookie-based sessions; once authenticated, a new session is created, and the user ID is stored in it, and when logging out, the session is cleared and a new session ID is generated. Alternatively, you could store username and password in the session, and check them on every request.
Use a session.
A session is identified by a cookie, true, but not the same as storing user auth info in the client cookie, which is bad for security. A session cookie stores a guid or a hash in the cookie, then identifies the session (either database or file system based, depending on your server's php settings) based on that.
I recommend you store the primary key from your user table, not any other info, then look up the user info every time - this allows you to change their validation status, or security level on the fly while they are logged in; otherwise they will have to log out and back in before your administrative changes take effect for them - IE. you can't boot them.
Also, don't store the username/password, because that requires a less efficient query than by the indexed primary key (even if they are indexed as well).
They are essentially the same, working hand-in-hand. When you create a session..say through PHP, a cookie is created to store the session id too. On the other hand, you would create another cookie if you want to implement a "Remember Me" option to prevent your users from logging in every time.
I'm not a PHP expert, but Session and Cookie are related. In other programming languages you have the option of creating "Cookie based session" or "Cookie-less session". I'm not sure about PHP though so maybe you are referring to different concepts.
I feel using session is much more safe and easy then using cookies. The reasons are as follows:
1) In cookie we can only store a single piece of information, whereas in a session we can store as many information as we want.
2) Being stored on hard disk of user, cookies can be played with. Being a person interested in hacking, I have done that and gathered useful information about the user. Sessions cannot be used for such a thing.
If its a small amount of data (just one variable), I would use a cookie. Here is the code...
setcookie("cookie name", "cookie value or variable name", time+ 3600, "\");
this code sets a cookie that is readable for any of your webpages. It also will delete its self in one hour.
You can also see if the cookie exists like this (to see if it has deleted its self).
if (isset($_COOKIE['cookiename']))
{
}
to collect a value from a cookie...
$value = $_COOKIE['cookiename']; //makes a variable for this cookie for your program