Tag Archives: session

Monitoring session to determine whether the user is online or not

Contents of articles

Scenario description session container add session remove session logout session failure

Supplement: listen to the change of session property. Session is independent of other session sharing schemes

Scene description

In the spring boot project, in order to simplify the message module, if there is a new message, write it to the database first. If the user is online, set newmessage flag = true in the session of the user receiving the message. The front end only needs to poll the session each time, and does not need to visit the database each time
the session needs to be obtained according to the user ID, so if the user logs in successfully, call the put method, log out or if the session fails, call remove.

Session container

Stores the session of the logged in user

public class LoggedUserSessionContext{
	//The default capacity is 16, you can set a reasonable initial value according to the number of visits to your site to avoid frequent expansion at the beginning.
    private static Map<Integer, HttpSession> sessionMap = new ConcurrentHashMap<>(128);

    public static HttpSession putIfAbsent(Integer userId, HttpSession session) {
    	// previously logged in a client, then return that session, to achieve multi-party login session sharing
	    return sessionMap.putIfAbsent(userId, session);        
    }

    public static void remove(Integer userId) {
        sessionMap.remove(userId);
    }
 
    public static HttpSession getSession(Integer userId) {
        return sessionMap.get(userId);
    }

}

Add session

After the user logs in successfully, execute the following code snippet

HttpSession session = LoggedUserSessionContext.getSession(user.getId());
            if(session != null){
                //Use the previously logged in id
                SpringUtil.setCookie("JSESSIONID", session.getId(), 60 * 30);
			}else{
				session = SpringUtil.getRequest().getSession();
				session.setAttribute(SessionKey.USER, user);
				LoggedUserSessionContext.putIfAbsent(user.getId(), session);
			}

After successful registration, execute the following code snippet

HttpSession session = SpringUtil.getRequest().getSession();
			session.setAttribute(SessionKey.USER, user);
			LoggedUserSessionContext.putIfAbsent(user.getId(), session);

Remove session

On cancellation

User user = (User)session.getAttribute(SessionKey.USER);
LoggedUserSessionContext.remove(user.getId());
session.invalidate();

When session fails

Use the listener to monitor the implementation of session and implement the HttpSessionListener interface


import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener {

    //Note: HttpServletRequest's getSession() method, if the current request does not correspond to the session will automatically create a session.
    //Using getSession(false) will not create session, if there is no session corresponding to the current request, it will return null.

   
    //New session created if unknown user browsing
    @Override
    public void sessionCreated(HttpSessionEvent event) {

    }

    //session Destroy User offline, logout login
    @Override
    public void sessionDestroyed(HttpSessionEvent event) throws ClassCastException {
        HttpSession session = event.getSession();
        Object userObj = session.getAttribute(SessionKey.USER);
        if(userObj != null){
        	User user = (User)userObj;
        	LoggedUserSessionContext.remove(user.getId());
        }
        
    }

}

Supplement:

Listen for the change of session property


With HttpSessionAttributeListener * * it is not recommended to listen to HttpSessionAttributeListener * * because it is too frequent

import java.util.HashSet;

import javax.servlet.ServletContext;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {

    //注Meaning: HttpServletRequest's getSession() method, if the current request does not correspond to the session will automatically create a session.
    //use getSession(false) will not create session, if there is no session corresponding to the current request, it will return null.

    //add property user login 
    @Override
    public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
        HttpSession session = httpSessionBindingEvent.getSession();
    }

    //Delete Properties User Logout
    @Override
    public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
        logger.info("--attributeRemoved--");
    }

    //Property substitution Information change
    @Override
    public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
        
    }

    //New session creation If unknown user browsing
    @Override
    public void sessionCreated(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        MySessionContext.AddSession(event.getSession());
    }

    //session Destroy User offline, logout login
    @Override
    public void sessionDestroyed(HttpSessionEvent event) throws ClassCastException {
        HttpSession session = event.getSession();
        MySessionContext.DelSession(session);
    }

}

Session independence

Instead of sharing sessions, you can use code logic to set pseudo sharing and change the container and data structure where sessions are stored

 private static Map<Integer, List<HttpSession>> sessionMap  = new ConcurrentHashMap<>(128);

In this way, each terminal can use session without affecting each other.

Solution to cross domain sharing problem of session

Before discussing the cross domain sharing of session, we should first understand what session has done and has not done

    HTTP is stateless, that is to say, the server does not know who has visited it, but sometimes we need to keep this state. For example, if the user logs in every time, the user experience is really bad. Session solves this problem. It maintains the user login information on the server and generates a jsessionid for the customer The client will take this jsession ID with it the next time it visits the server, and the server will search the user information according to this ID. Of course, the disadvantages of session are also obvious. Session exists in the memory of the server. If there are too many sessions, the performance of the server will be affected. Because session is only in one server, when there are multiple servers, accessing other servers will definitely fail.

After making clear what session does and its defects, it is much easier to solve the problems existing in session. Let me briefly talk about five solutions

Session stickysession copy session centralized storage cookietoken

Session sticky: it means that requests from the same client will fall on the same server, because they will not fall on other servers, so cross domain problems will not occur. But the disadvantage of this scheme is very obvious, that is, no matter what algorithm is used, the user will decide which server the user’s request falls on, which may cause a single point of pressure, and if a server has problems, it may cause people in an area to be unable to access

Session replication: refers to the synchronization of session information between servers, that is, all session information is saved on each server. The disadvantages of doing so are also very obvious. As mentioned above, session is stored in memory, which will seriously affect the performance of the server. Of course, you can also store it in the database, but it will greatly affect the response speed. Another disadvantage is that when the traffic is too large, it will cause a lot of network overhead due to the problem of mutual synchronization

Session centralized storage: it refers to the centralized storage of sessions in a third-party server, which can be redis, database or other things. When you need to access it, go to this server. This also has some disadvantages. First of all, it is a single point problem. If the server goes down, all services are unavailable. Therefore, it is necessary to build a cluster here, which will waste server resources. Another point is that every time you verify, you need to check with this server, which will increase the network overhead and reduce the access speed

Cookie: the state information is no longer saved in the server, but in the client. Every time the client visits the server, it brings the information to the server. However, cookies also have many problems. The most concerned problem is security. Because information is stored on the client, it is easy to be stolen and tampered with. Of course, there are solutions to these security problems. This is not the main reason for restricting cookies. The real reason for restricting cookies is that many devices do not support * * cookies

Token: similar to cookie, token is maintained by client, and information is stored in client, which is platform independent. A token is essentially a string given by the server to the client, which contains some authentication information. It is equivalent to an identity token. You can get its service with this token. Compared with cookie, token is more flexible and can be generated anywhere. The permission system based on token is very easy to implement

Of course, the above five solutions are not the only ones. I just listed a few representative ones.

Solutions are used to solve problems. There is no good saying about the above solutions. Only the right one is the best.

Exception loading sessions from persistent storage

Tomcat error:
serious: IOException while loading persistent sessions: java.io.EOFException
Exception loading sessions from persistent storage

Error Description:
0 The session data stored in the hard disk failed to read. Eofexception indicates that the end of the file or the end of the file stream was unexpectedly reached during the input process, resulting in the failure of reading data from the session. This exception is a problem of Tomcat itself, generally because some active sessions were persisted when Tomcat was shut down abnormally last time. When Tomcat was restarted, Tomcat tried to recover these sessions N but failed to read

Solution:
find the corresponding project under Tomcat / work / Catalina / localhost session.ser File, and then delete it

The original text is reproduced from: http://blog.csdn.net/angeldhp/article/details/4742075

If the iframe in IE refers to the cross domain site page, the session fails

Problem scenario:

Personal confidence page through the IFrame nested third party page, domain name is different, call the third party interface, in Chrome test normal, in Internet Explorer is embedded in the page Session invalidation. (Session is based on cookie implementation, reference page is not allowed to use cookie)

Problem analysis:

The IE-supported P3P(Platform for Privacy Preferences Project (P3P) Specification) protocol by default prevents third party cookies without Privacy security claims, and Firefox does not currently support P3P security features, nor does it naturally exist in Firefox.

Solutions:

1. Modify the setting of the Client
so that the Client can accept cookies from any website (specifically set in the privacy page of IE option to add B site to the trusted site)
or set both domains to the trusted site

2. The domain of the application modifies the
simple scheme: two applications use the same domain
Complex solution: you can force changes to

through setdomain in pages loaded by the iframe. 3. P3P
first: output the host header declaration of P3P in the content to be embedded (the site the iframe points to) as follows:
Open IIS Manager InetMgr to be embedded in the iFrame source site or directory, right-click to open the Properties box and toggle to HTTP headers Add custom HTTP headers P3P Custom HTTP headers CP=”CAO PSA OUR” Close the properties box and exit, effective immediately
Response.addheader (“P3P”,”CP=CAO PSA OUR”);

Transfer: https://www.cnblogs.com/weibozeng/archive/2013/11/06/3410904.html

php open(/var/lib/php/session/sess_4ofxxx, O_RDWR) failed: Permission denied (13)

Meet
session_start () :
open (/ var/opt/remi php72/lib/PHP/session/sess_4ofga8ehv8s2ct2b9dnn40qtp2, O_RDWR) failed: Permission denied (13)
Error message

session_start(): open(/var/opt/remi/php72/lib/php/session/sess_4ofga8ehv8s2ct2b9dnn40qtp2, O_RDWR) failed: Permission denied (13)

Solutions:

sudo chmod 1733 [报错的session的路径]

The solution for the above example is as follows

sudo chmod 1733 /var/opt/remi/php72/lib/php/session

Refer to the article