I was wondering if there was a "standard" way for handling persitent HTTP sessions in a GAE based web app. Let me explain my issues.
If I only use this.getThreadLocalRequest().getSession() to get a session, this session will be automatically invalidated once the user closes the browser.
If I go with Cookies (so the session will persist until the cookie expires or the user erases his cookies), I need to have a kind of mechanism for validating that the sessionID stored in the cookie actually belongs to a valid session. I've thought about storing a key value pair of sessionID, HttpSession in a concurrentHashMap, but now I run into the problem that this hashmap will be available only for the current instance, therefore I might run into consistency problems.
The last solution I thought of was keeping track of the session in the datastore, but it seems pretty ridiculous to me having to query the datastore each time I receive a request.
Maybe I'm totally out of the track and there's a really simple way to achieve what I'm trying to do: Http sessions that persist across browser restarts and multiple gae instances.
Thanks!
Rodrigo.
You typically use a cookie to implement remember-me. The idea is to generate a random and unique cookie for an authenticated user, store it with the rest of the user information in the database, and send the cookie to the client browser.
Now, when the client comes back 5 days later, the cookie is sent with its first request to your application. At this time, if the user is not authenticated yet, you can extract the cookie from the request, find the user in the database who owns this cookie, and automatically authenticate him as if he sent his credentials.
This solution doesn't need to modify anything to how the sessions are handled by GAE.
Related
I've read in several places that it's not recommended to store a JWT in the browser, either in storage or as a cookie. Even if it was, for the current application I'm developing, we have the JWT stored on a java servlet, and are using a separate React app as a frontend.
I was thinking that I could just give each user an ID in a cookie and then check that their session is still valid by comparing the associated JWT.
Is there some recommended method for keeping track of a user's session with a JWT without actually sending the JWT to the user at any point? Every search I try results in a dozen articles telling me not to send JWT to the browser and store it there, but I wasn't planning to anyway. I'd like to avoid having to handle multiple methods of maintaining a user's session, and the JWT is something that isn't optional at this point.
I am new to web app development.
Basically, I have got a GWT based web app. A user first needs to login. After successfully authenticated himself, he will be taken to the second page (actually another GWT view in the same page).
The login will generate a pair of keys from another web service. These key will be used for future communication with the web service, it is like:
client -> server => web service
Now the problem comes, I cannot save the key pair in a database. What shall I do?
I have been told I can put the key in a cookie and send back to the client. Every time the client raise request the cookie will be sent to the server.
I have also been told to set the keys as the session key and send them to the client.
I am note quite sure what is the different between these two methods. Are they applicable? or secure?
Many thanks
Both methods are applicable. The first one (using cookies) will rely on the user side (its cache). Second one, will keep data on server side (session). As a rule (although it's arguable), you never trust the client. What if client made a clear cache to his browser.
Even for security (I am not an expert here), I think storing data on server is always safer.
You can use both cookie as well as session or a combination of both to achieve this. Cookie are usually created when you launch your application (Also you can create it as and when required). The disadvantage of this is, it is temporary. As soon as you clear the cache or cookies, whatever cookie you created will be removed. If you store it on server side i.e., in session you must make sure to create a separate key value pair for each set of user, as many users can connect to the same server. The best approach will be using both the option together. I.e., to save a cookie and validate the session id.
This link will help you understand how create a cookie and session.
I am having some issues with my web application while doing a performance test with Jmeter. My question is not around Jmeter instead, it's around a simple Servlet session management behavior.
So we have a web application, where in when you request a login page, it passes back a "Session Id" in response headers and that is used for subsequent request made by browser. Session Id is passed along with username and password and if authenticated a new session id is returned and session is maintained with that session id going ahead.
This is using cookies.
Now in Jmeter we have a thread based approach for load testing. When I run threads parallely what is essentially happening is that each thread request a login page and somehow only the last thread to request login page is authenticated as I feel that subsequent login page that comes with a new session id in cookie, invalidates the old or other session ids.
This is inspite of the fact that each thread is a different session and has it's own cookie manager. It's quite wierd.
However my questions are:
Does it make sense to have session id coming with login page; I see that maybe session is created as soon as application is accessed, but is it that, what sets a new cookie with session id? This application was already written so I am just wondering.
If each thread's session id is being overriden in jmeter does that mean, that i am not able to allocate a seperate cookie manager properly? Also even if threads are different sessions is there a possibility, old session id or cookie would be discarded?
How would Server know to invalidate the session id/cookie for subsequent requests? I am sure, not basis of IP address of requestor, as different browsers would still let me open parallel multiple sessions.
Any ideas, clarifications and light on the issue would be much appreciated.
Server will just timeout the session it definitely sounds like you are over writing cookies here.
Have you tried seeing how it manages by including session ids in the url (simulate cookies being disabled in the browser) Does this work?
Has this been solved at all?
I would say that having a session id in the login page is quite unusual. Session are meant for storing data server side and associate that data to connected users. Of course, prior to authenticate the user, there shouldn't be any data server side.
Best way managing session in Java. I heard that cookies are not reliable option for this as they gets stored into browser and can be accessed later on? Is this correct? If possible please come up with the answers with the coding example.
Which is the best among:
URL Rewriting: Server will add an additional parameter at the end of URL link
Hidden parameter in Form: server will add an additional parameter at every form in HTML
cookie: Server will ask browser to maintain a cookie.
The session management (client identification, cookie handling, saving session scoped data and so on) is basically already done by the appserver itself. You don't need to worry about it at all. You can just set/get Java objects in the session by HttpSession#setAttribute() and #getAttribute(). Only thing what you really need to take care of is the URL rewriting for the case that the client doesn't support cookies. It will then append a jsessionid identifier to the URL. In the JSP you can use the JSTL's c:url for this. In the Servlet you can use HttpServletResponse#encodeURL() for this. This way the server can identify the client by reading the new request URL.
Your new question shall probably be "But how are cookies related to this? How does the server do it all?". Well, the answer is this: if the server receives a request from a client and the server side code (your code) is trying to get the HttpSession by HttpServletRequest#getSession() while there's no one created yet (first request in a fresh session), the server will create a new one itself. The server will generate a long, unique and hard-to-guess ID (the one which you can get by HttpSession#getId()) and set this ID as a value of the cookie with the name jsessionid. Under the hood the server uses HttpServletResponse#addCookie() for this. Finally the server will store all sessions in some kind of Map with the session ID as key and the HttpSession as value.
According to the HTTP cookie spec the client is required to send the same cookies back in the headers of the subsequent request. Under the hood the server will search for the jsessionid cookie by HttpServletRequest#getCookies() and determine its value. This way the server is able to obtain the associated HttpSession and give it back by every call on HttpServletRequest#getSession().
To the point: the only thing which is stored in the client side is the session ID (in flavor of a cookie) and the HttpSession object (including all of its attributes) is stored in the server side (in Java's memory). You don't need to worry about session management youself and you also don't need to worry about the security.
See also:
Authenticating the username, password by using filters in Java (contacting with database)
How to redirect to Login page when Session is expired in Java web application?
How to implement "Stay Logged In" when user login in to the web application
All Java web frameworks support cookies or URL-encoded session IDs. They will chose the correct approach automatically, so there is nothing you need to do. Just request the session object from your container and it will handle the details.
[EDIT] There are two options: Cookies and a special URL. There are problems with both approaches. For example, if you encode the session in an URL, people can try to pass the session on (by putting the URL into a mail, for example). If you want to understand this, read a couple of articles about security and build app servers. Otherwise: Your Java app server will do the right thing for you. Don't think about it.
The cookie just stores the session ID, this ID is useless once the session has expired.
Servlet specification defines the API for accessing/setting session data in standard J2EE application. Also it defines that session data is stored on the server-side and nothing is transferred to the client except the session identifier. There are 2 mechanisms how session id is transferred:
1) request URL e.g. jessionid=....
2) cookie
Mechanism is determined automatically based on client capabilities.
EDIT. There is no best option, there is servlet specification that defines the way.
Http is a stateless, client-side pull only protocol.
To implement a stateful conversation over it, Java EE Web Server need to hide some information (which is sessionid) in client-side and the mechanism it can use should follow HTTP and HTML spec.
There are three ways to accomplish this goal:
URL Rewriting: Server will add an additional parameter at the end of URL link.
Hidden parameter in Form: server will add an additional parameter at every form in HTML.
cookie: Server will ask browser to maintain a cookie.
Basically, modern web server will have a "filter" to choose which way to use automatically.
So if Server detected that browser already turn off cookie support, it will switch to other ways.
2 important questions:
Which web technology are you using? JSF, Struts, SpringMVC or just plain servlets/JSPs.
Servlets/JSPs already give you the session support you need. JSP Example: Hello, <%= session.getAttribute( "theName" ) %>
I really don't think you have something to worry about cookies, since the data is stored safely in the server and handeling the cookie is done automaticlly.
Is your application installed on a single server?
If YES than you have no problem, use the servlet session option.
if NO than you gotta find another way to do this. Like using a sticky session, or maybe parse the entire session object in the requests/responses as a field. This option indeed requires you to take security measures.
I work on a task that involves moving/traversing from one application to another. The applications are in separate JVMs.
While traversing to the other application, I keep track of the session ID. However, as I traverse back and forth, a new session gets created. Is there any way for me to get back the same session, using the sessionId that I retain, when I navigate back into my parent application from a child application?
Environment: J2EE with WebSphere.
As mentioned by Mork0075, the sessionID is tied to the cookie name and the server domain. If you're using the same server domain for two apps on separate JVMs, I see two options to maintain the session when switching between applications:
The long shot:
1) If you're using a database for session replication purposes, you can use the same database for both applications, and the sessionID will be available for both apps. The one problem I see here is that the objects in the session may not be available on both sides, since the code would be different etc. They'd probably clobber the other side's session objects unless you maintained the code and such on both sides so the objects were available.
The likely possibility:
2) Use different cookie names for the session on one of the two apps. By default, sessions use JSESSIONID as the cookie, and when you switch to the second app, it tries to look up a session based on that cookiename and can't find it. So, it creates a new sessionID and sends it back to the browser, thus causing your sessionID to change and not be available when you switch back to the original app. However, if you change the second app's sessionID to something else (say, JSESSIONID2) your browser would end up with two valid sessionIDs that would each be valid on their correct application. You can change the name via the administration console under the application server's Session Management->Enable cookies page.
I'am not sure if this helps, but in a ONE application scenario, you would submit a sessionID with every reponse, save it in the URL, a cookie or as a hidden field. By submitting a new request to the server, the sessionID is also submitted, to resolve it at server side. In my understand switching from one application to another means, that you have to give the sessionID with the user, across the applications. If you save the sessionID in a cookie, this perhaps is not possible, because the cookie is restricted to a certain server domain. So ensure that the session is still valid and the sessionID is present after returning to the application started.
You shouldn't have to do this manually. Most app servers support Single Sign On (SSO) so that you can log in to one application and have access to all the applications in the same SSO domain. The app server will keep track of session ids and link them to an HTTPSession object specific to the web app.
See http://publib.boulder.ibm.com/infocenter/wasinfo/v6r1/topic/com.ibm.websphere.base.doc/info/aes/ae/csec_sso.html