I have a system that is deployed with the link http://192.168.2.6:8484/DTR and upon logging in, it stores the user's info via session.setAttribute("user", user); However, when another user logs in, it overwrites the info of the first user as it again calls session.setAttribute("user", user);. So how can I really save the user's info so that more than two people can access the system at the same time?
This is what is currently happening:
I have two websites that are open.
I login in the first website (username: user1). Shows Hello, user1
I login in the second website (username: user2). Shows Hello, user2
I refresh the first website. It will now show Hello, user2
So how can I enable multiple users to access the website?
As discussed in the comments, the reason is both the users are logged in from the same browser and same system. So the JSessionId is same and hence the attributes are overriden.
Solution:Try with a different browser
You first get user attribute and set it if it's not there and session is new
user = session.getAttribute("user");
if (user == null&& session.isNew())
session.setAttribute("user", user);
Also please check if you are getting different session for different users session.getId() ... if not it might be the problem JSESSIONID cookie. The servletcontainer set a Cookie in the Set-Cookie header of the HTTP response with JSESSIONID as cookie name and the unique session ID as cookie value.
Related
I set a userId in the session object on the pageload of homepage of my application like below
HttpSession session = req.getSession();
session.setAttribute("userId", validUserId);
When user navigates to different page of the application, I fetch this userId using normal way like below and I save this userId in database later.
HttpSession session = request.getSession();
String userId = (String) session.getAttribute("userId");
This works for almost 95 times out of 100 calls. I am able to fetch the userId and store in database, but for 5 calls, all I get is a blank userId object.
I am not able to reproduce this issue in lower environments, so its bit difficult to understand what the issue is.
I have set the automatic expiry of the pages to 20 mins by adding the property in web.xml and then using it in jsp page.
Can some one please guide as to what could be the root cause of this issue?
Found the root cause.
When i am displaying the expiry page and invalidating the session, if user clicks on back button of the browser, it was displaying the old page again and if data is submitted now, then this variable is not available as session is already invalidated previously. Need to fix back button issue.
Just wondering if my following authentication method is correct or not. Is there any pitfall or anything missing? Suggestions and discussions are very welcome.
1> User provide user name and password, and send to the server by RPC. Comparing with the hashed value stored in DB.
2> Assuming the user name and password are accurate, an Auth Token is saved in session. The auth token will be checked when accessing the servlets.
3> The user id (integer) is returned to the client by RPC onSuccess. The user id is saved in a static variable on the client side.
4> Whenever the user specific information is needed, the rpc call with the user id (the static variable) will be sent to the server for database query.
Thanks
You'd better return the token to client side, and verify token instead of user id.
If user id is used, a user A is logged in, then another user can send request to server pretended to be user A. Your authentication method failed to protect data.
You don't need to send a user id to the client. The server has already all information he need's to recognize the user.
This code snippet creates a session cookie, with session.getId() you get the content of it, which you should save to recognize the user:
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession(true);
Then when the user calls your Server, you just read back the session id.
HttpServletRequest request = this.getThreadLocalRequest();
HttpSession session = request.getSession(false);
With session.invalidate() you can destroy the session, it's also possible to store objects in the session.
The this.getThreadLocalRequest() only works in *Impl .
you quoted
3> The user id (integer) is returned to the client by RPC onSuccess. The user id is saved in a static variable on the client side.
If a user refreshes his page, the value that is stored on the client side static field will be reset, right? in that case will the session ends? and user will be prompted for login again?
I have a very basic question how the creation of HTTPSession works.I know you folks will fire me on looking at this question as similar kind
of questions exist.But there is reasoning why i am asking this question Here it is :-
I know httpsession is unique to web browser and server creates it when we do HttpServletRequest.getSession first time.It will maintaintain the same session till we
close the browser. But i have little bit different scenario.I Have a web application on one tomcat instance say T1.On welcome page of this web application
i have provided two links on click of which takes me to same java servlet(S1) of different web application hosted on another tomcat instance T2 (these two links
opens two seperate pop up windows). Now first i click the link1 and inspect the sessionId in S1 and find its value as 1678. Now first i click the link2 and
inspect the sessionId in S1 and find its value again as 1678. My question here is why i am getting the same session id for both the requests origintaing
from link1 and link2? what can i do to to get the different session for both of these requests?
What i tried after looking for possible solutions on net :- On click of link1, in Servlet S1 , i copied session attributes, invalidate it and create new one.
Say new session id is 8765 . Now i click the link2 and found the same session in this request too. So i further invalidate it and creates new one(say
new session id is 4897). Ideally it should expire the first browser session (generated on click of link1). To verify it,i click anywhere on pop up 1 it does not get
expired but i see again last generated session id i.e 4897. I am not getting why it attaching the same session id with both pop up windows?
Folks Thanks for your patience for taking your time out and read this long scenario?
Edit :-
Cookie[] cookies = req.getCookies();
if(cookies!=null)
for (int i = 0; i < cookies.length; i++) {
cookies[i].setMaxAge(0);
context.getResponse().getHttpServletResponse().addCookie(cookies[i]);
}
HttpSession myAppSession = req.getSession();//line 1
Assume on click of link1 i get session id as 1234,then after click of link 2 also i get the same session id. As per my understanding, after executing the code above line 1 , i should get the different session id as i am setting the MaxAge as0 before getting the session. But its not happening?
I think this is what you are looking for :
By default session tracking happens by cookies. WebServer sends the session id to the browser in the form of cookie. And, the browser send the cookie having session id for the subsequent requests.
How does the browser identifies which cookies to send for a link/request?
It is based on the these parameters. If the request matches these paramters the browser sends that particular cookie:
Domain: The domain name to which the request is made. Verify in your case if the domain name is same for two instances
Path: If the path name is same. Web Server send the context root as the path , requests under same context root share cookies.
Secure: Server sends if the given cookie is secure or not. Meaning, if the cookie can be sent on non-secure channel.
These parameters will let the browser to send the cookies to the server. And because the same cookie is sent for both the instances you are having. I think the session id is being shared.
If the request propeties such as Request URI, domain and path(i.e, context root) are same between requests, there is no way to tell the browser to use different cookies.
You have some options below:
Use different domain names.
Use different context roots.
Have a LB in front of two nodes and redirect to the correct node based on Session id
I am using the following code to delivery the user to a Welcome page if they are already logged in, or back to the login page if they are not.
HttpSession session = request.getSession(false);
if(session == null){
request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
}else{
//User already logged in. Send to home.
response.sendRedirect("Welcome");
}
First time around, it works fine, but if I reload the page even once it sends the user to the welcome page and inevitably sends me back a 500 error because there are elements on that page that cannot be loaded because the user log in code has not been executed.
Does a session get started automatically even if request.getSession(true) is not declared when a page is reloaded? Is there a way to prevent this?
Probably the session is being created upon forwarding to login.jsp. That's necessary because the user has to be assigned to an unauthenticated request and then authenticate it. If you want to redirect based on whether the user is logged in or not, use SessionContext's getCallerPrincipal.
For more info, check this (somewhat old, but still relevant) article
The method request.getSession(false) returns null if there is no current session. I suggest to compare a key too.
Please take a look at this threads.
Do JSPs always create a session?
How do servlets work? Instantiation, session variables and multithreading
I have a website built on App Engine(Java) and need user use Google Account to login.
The situation is that:
User Adam has multiple accounts.
User Adam login with account Adam1 and get his Adam1 data in browser page A.
He clicked logout link, but opened it in another tab page B(the same browser of course)
He login with another account Adam2 in browser page B get his Adam2 data shown.
He then returned to browser page A and made some changes to his data and then send to server, at this time my app would recognize the current user is Adam2 , and the changes would be taken on Adam2, it does not match the status with its current page A, our user may be confused.
I thought maybe I can attach a userID parameter while making change request to the server and server side will compare the current user id with this userID parameter to make the change request processed or return a refresh command to make the out-of-date page be refreshed to the current account's if the ids are not same.
What is the best practice to handle this situation?
Put a hidden field on your forms that is a combined hash of the session ID and the user ID. When your server processes the request, double check that the combined hash sent along with the request matches what you expect. If either the user or the session is wrong, the hash won't match, and you can report an error appropriately.
Presumably the user would be identified by a Session ID that is send as Cookie information. Adam on site A will have a different Session ID than Adam on site B because of the differing login. Also presumably the form page will be protected such that a user needs to be logged in in order to access it.
When Adam logs out on page B, the old session is destroyed on the server and the login becomes invalid. When Adam submits the form from page A, the browser doesn't know this has happened and will submit the form together with the old Session ID. The server will (should) reject this submit since the session has already expired.
Hence, in a properly coded Session/User management system, this becomes a non-issue. The critical point is to renew/invalidate the Session ID upon logout.