question on GWT, Cookies and webpage directing

molleman picture molleman · Jun 4, 2010 · Viewed 8.9k times · Source

i am using gwt to create a website. this question is regarding a login page and cookies to save login details. GWT allows you to create a website within a single webpage.

my application runs on one webpage. i have the application set up as , there is a login box with a login button, and if the details are correct it will load up the underlying UI and removes the login box.

so that means every time i refresh my page the application brings me to the login page. is there anyway to set up a cookie that hold the information of the user for example a day, that would input the details into the login box and sign in automatically,

also the logout button within the web app would remove the information in the cookie and bring you to the login page (remove the cookie information and direct you to the login part of the webpage).

or would there be a different approach.

Answer

Igor Klimer picture Igor Klimer · Jun 4, 2010

I'd say you almost got it right :D Here's how I handle login/logout in my application:

  1. The user loads the page - if he has a cookie set with a token (see next points for more info), send that token to the server to check if it's still valid. If it's valid, you are logged in, go to point 5. See notes below on how to handle an invalid token.
  2. The user inputs user/pass combination. This information is sent to the server (it'd be best to send it over an encrypted connection, but it's hard to achieve with GWT - for example, see this question).
  3. The server checks if the user/password hash (see below) combination matches with what's in the database/whatever. If so, it generates a token (just some random, rather long string, like an UUID) and sends it back to the client.
  4. If the user checked the "Remember me" checkbox during login, store the token in a cookie with a future expiration date (refer to other guides/questions on what is the recommended time period).
  5. When the client receives the token, it should use it for every request made to the server that you want only authenticated users to perform. There, the server checks if the token is valid (you have to keep track of token(s)/user pairs in your DB) and if so, authorize the transaction/whatever. Here's the catch: if you rely only on the cookie, you'll be vulnerable to a XSRF attack. That's why you should pass the token also (the cookie is transferred automagically - that's why a XSRF attack is possible) as part of the request (you know, like as an additional field in JSON or a field in a POJO you send via GWT-RPC or even in the HTTP header).
  6. On explicit logout (clicking the "Logout" link, etc.), send an information to the server that this user has just logged out. The server should then delete/invalidate the token. It should do this regardless of the "Remember me" option - since explicit logout means the user wants to delete login information on that PC/browser and prevent others from logging in as him/her. If the user just closes the browser/page and you've set the cookie correctly in point 4 (meaning, it won't expire on browser close - again, only if the "Remember me" option was chosen), on next visit the user should get automatically logged-in in point 1.

Some additional notes

  • This is very important: remember to check on the server side if the token passed through the cookie equals the one passed as part of the request/payload.
  • Don't store the passwords in your database as plain text - store hashes of the passwords. Use BCrypt for maximum security. That's why I wrote that you should compare password hashes, not the actual passwords.
  • When the server encounters an invalid token, this can mean a number of things - from normal to alerting. In general, it's good to log these situations and regularly check the logs for any abnormal activity.
    1. User hadn't visited the site for a looong time and the token expired. Make sure you handle token expiration properly on client side (correct expiration dates on cookies should result in the user being redirected to the login page, without sending the expired token) and server side (a special task that scans daily the token list and deletes the expired ones?)
    2. Maybe you've put some other restrictions on token validation - like the token can't be expired and the current attempt must be from the same IP as the one the token has been originally generated for.
    3. There was an error when sending the request and it came malformed/corrupted - can't do much about this, but redirect the user to the login page
    4. A third-party is trying to log in using a handcrafted token. If you use stupidly easy to guess tokens (like based on the username, rot13, own super-special-awesome "encryption" etc.) then you will get bitten by this sooner or later. UUID is an example of a good token candidate - as the name implies, it's a universally unique identifier - meaning no two users should have the same UUIDs and the UUIDs themselves are random and long.

Security in AJAX applications is serious business - I've seen too many web applications with easy to exploit security holes... Make sure you understand completely what and why you are doing. If you have any questions, don't hesitate to ask :)


Update 2015-06-12: GWT - Security RPC XSRF