Session 会话或cookie混淆

Session 会话或cookie混淆,session,servlets,cookies,Session,Servlets,Cookies,我在一些网站上看到,用户登录到他们的帐户,然后关闭浏览器 关闭并重新打开浏览器后,他们的帐户仍在登录 但是一些网站,不能这样做 我很困惑,这算是会话还是cookie 如果我想这样登录我的网站,我是否必须设置session.setMaxInactiveInterval()或cookie.setMaxAge()?*此答案有严重缺陷,请参阅评论* 您的问题是关于会话跟踪的 [第1部分]:会话对象 HTTP请求是单独处理的,因此为了在每个请求之间保留信息(例如,关于用户的信息),必须在服务器端创建会话

我在一些网站上看到,用户登录到他们的帐户,然后关闭浏览器

关闭并重新打开浏览器后,他们的帐户仍在登录

但是一些网站,不能这样做

我很困惑,这算是会话还是cookie


如果我想这样登录我的网站,我是否必须设置
session.setMaxInactiveInterval()
cookie.setMaxAge()

*此答案有严重缺陷,请参阅评论*


您的问题是关于会话跟踪的

[第1部分]:会话对象

HTTP请求是单独处理的,因此为了在每个请求之间保留信息(例如,关于用户的信息),必须在服务器端创建会话对象

有些网站根本不需要会话。用户不能修改任何内容的网站不必管理会话(例如,在线简历)。在这样的网站上,您不需要任何cookie或会话

创建会话:

在servlet中,使用HttpServletRequest对象中的
request.getSession(true)
方法创建新的HttpSession对象。请注意,如果使用
request.getSession(false)
,如果尚未创建会话,则将返回null

设置/获取属性:

会话的目的是在每个请求之间保留服务器端的信息。例如,保留用户名:

session.setAttribute(“name”、“MAGLEFF”); //铸造 字符串名称=(字符串)session.getAttribute(“名称”); 销毁会话:

如果保持非活动状态的时间过长,会话将自动销毁。但您可以手动强制销毁会话,例如,在注销操作的情况下:

HttpSession session=request.getSession(true);
session.invalidate();
[第二部分]:所以。。。加入黑暗面,我们有饼干吗?

饼干来了

JSESSIONID:

每次使用
request.getSession()
创建会话时,都会在用户计算机上创建JSSessionID cookie。为什么?因为在服务器端创建的每个会话都有一个ID。除非您没有正确的ID,否则无法访问其他用户的会话。此ID保存在JSESSIONID cookie中,并允许用户查找其信息

何时删除JSESSIONID?


JSESSIONID没有过期日期:它是会话cookie。与所有会话cookie一样,它将在浏览器关闭时被删除。如果使用基本的JSESSIONID机制,那么在关闭并重新打开浏览器后,会话将变得不可访问,因为JSESSIONID cookie已被删除

请注意,客户端无法访问会话,但仍在服务器端运行。设置MaxInactiveInterval允许服务器在会话处于非活动状态的时间过长时自动使会话无效

邪恶地摧毁JSESSIONID

只是为了好玩,有一天我在一个项目中找到了这段代码。它用于通过使用javascript删除JSESSIONID cookie使会话无效:


函数删除\u cookie(检查\u名称){
//首先,我们将此cookie拆分为名称/值对
//注意:document.cookie只返回name=value,不返回其他组件
var a_all_cookies=document.cookie.split(“;”);
变量a_temp_cookie=“”;
变量cookie_name=“”;
var\u值=“”;
var b_cookie_found=false;//设置布尔t/f默认值f
//var check_name='JSESSIONID';
var path=null;
对于(i=0;i-1)
{
b_cookie_found=true;
//我们需要处理cookie没有值但存在的情况(no=sign,即):
如果(a_temp_.length>1)
{
cookie\u value=unescape(一个临时cookie[1]。替换(/^\s+\s+$/g,);
document.cookie=cookie\u名称+“=”+cookie\u值+
“路径=/”+
“到期日=1970年1月1日星期四00:00:01 GMT”;
//警报(“cookie已删除”+cookie\u名称);
}
}
a_temp_cookie=null;
cookie_name='';
}
返回true;
}
//毁灭
删除_cookie(“JSSessionID”);
。使用JavaScript,可以读取、修改JSESSIONID,使其会话丢失或被劫持

[第3部分]:关闭浏览器后保留会话

关闭并重新打开浏览器后,他们的帐户仍处于活动状态 登录。 但是一些网站,不能这样做。 我很困惑,它被认为是会话还是cookie

这是饼干

我们看到,当web浏览器删除JSESSIONID会话cookie时,服务器端的会话对象丢失。没有正确的ID,无法再次访问它

如果我想让我的网站像那样登录,我必须设置吗 session.setMaxInactiveInterval()或cookie.setMaxAge()

我们还看到,
session.setMaxInactiveInterval()
可以防止无限期地运行丢失的会话。JSESSIONID cookie
cookie.setMaxAge()
也不会让我们有任何进展

使用会话Id为的持久cookie:

我在读了这篇文章后得出了这个解决方案
<listener>
    <listener-class>
        fr.hbonjour.strutsapp.listeners.CustomServletContextListener
    </listener-class>
</listener>

<listener>
    <listener-class>
        fr.hbonjour.strutsapp.listeners.CustomHttpSessionListener
    </listener-class>
</listener>
/**
 * Instanciates a HashMap for holding references to session objects, and
 * binds it to context scope.
 * Also instanciates the mock database (UserDB) and binds it to 
 * context scope.
 * @author Ben Souther; ben@souther.us
 * @since Sun May  8 18:57:10 EDT 2005
 */
public class CustomServletContextListener implements ServletContextListener{

    public void contextInitialized(ServletContextEvent event){
        ServletContext context = event.getServletContext();

        //
        // instanciate a map to store references to all the active
        // sessions and bind it to context scope.
        //
        HashMap activeUsers = new HashMap();
        context.setAttribute("activeUsers", activeUsers);
    }

    /**
     * Needed for the ServletContextListener interface.
     */
    public void contextDestroyed(ServletContextEvent event){
        // To overcome the problem with losing the session references
        // during server restarts, put code here to serialize the
        // activeUsers HashMap.  Then put code in the contextInitialized
        // method that reads and reloads it if it exists...
    }
}
/**
 * Listens for session events and adds or removes references to 
 * to the context scoped HashMap accordingly.
 * @author Ben Souther; ben@souther.us
 * @since Sun May  8 18:57:10 EDT 2005
 */
public class CustomHttpSessionListener implements HttpSessionListener{

    public void init(ServletConfig config){
    }

    /**
     * Adds sessions to the context scoped HashMap when they begin.
     */
    public void sessionCreated(HttpSessionEvent event){
        HttpSession    session = event.getSession();
        ServletContext context = session.getServletContext();
        HashMap<String, HttpSession> activeUsers =  (HashMap<String, HttpSession>) context.getAttribute("activeUsers");

        activeUsers.put(session.getId(), session);
        context.setAttribute("activeUsers", activeUsers);
    }

    /**
     * Removes sessions from the context scoped HashMap when they expire
     * or are invalidated.
     */
    public void sessionDestroyed(HttpSessionEvent event){
        HttpSession    session = event.getSession();
        ServletContext context = session.getServletContext();
        HashMap<String, HttpSession> activeUsers = (HashMap<String, HttpSession>)context.getAttribute("activeUsers");
        activeUsers.remove(session.getId());
    }

}
public class Servlet2 extends AbstractServlet {

    @Override
    protected void doGet(HttpServletRequest pRequest,
            HttpServletResponse pResponse) throws IOException, ServletException {
        String username = (String) pRequest.getParameter("username");
        String password = (String) pRequest.getParameter("password");
        // Session Object
        HttpSession l_session = null;

        String l_sessionCookieId = getCookieValue(pRequest, "JSESSIONID");
        String l_persistentCookieId = getCookieValue(pRequest, "MY_SESSION_COOKIE");

        // If a session cookie has been created
        if (l_sessionCookieId != null)
        {
            // If there isn't already a persistent session cookie
            if (l_persistentCookieId == null)
            {
                addCookie(pResponse, "MY_SESSION_COOKIE", l_sessionCookieId, 1800);
            }
        }
        // If a persistent session cookie has been created
        if (l_persistentCookieId != null)
        {
            HashMap<String, HttpSession> l_activeUsers = (HashMap<String, HttpSession>) pRequest.getServletContext().getAttribute("activeUsers");
            // Get the existing session
            l_session = l_activeUsers.get(l_persistentCookieId);
        }
        // Otherwise a session has not been created
        if (l_session == null)
        {
                    // Create a new session
            l_session = pRequest.getSession();
        }

            //If the user info is in session, move forward to another page
        String forward = "/pages/displayUserInfo.jsp";

        //Get the user
        User user = (User) l_session.getAttribute("user");

        //If there's no user
        if (user == null)
        {
                    // Put the user in session
            if (username != null && password != null)
            {
                l_session.setAttribute("user", new User(username, password));
            }
                    // Ask again for proper login
            else
            {
                forward = "/pages/login.jsp";
            }
        }
        //Forward
        this.getServletContext().getRequestDispatcher(forward).forward( pRequest, pResponse );

    }
/**
 * 
 * @author BalusC
 */
public static String getCookieValue(HttpServletRequest request, String name) {
    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        for (Cookie cookie : cookies) {
            if (name.equals(cookie.getName())) {
                return cookie.getValue();
            }
        }
    }
    return null;
}

/**
 * 
 * @author BalusC
 */
public static void addCookie(HttpServletResponse response, String name, String value, int maxAge) {
    Cookie cookie = new Cookie(name, value);
    cookie.setPath("/");
    cookie.setMaxAge(maxAge);
    response.addCookie(cookie);
}

/**
 * 
 * @author BalusC
 */
public static void removeCookie(HttpServletResponse response, String name) {
    addCookie(response, name, null, 0);
}

}
public class LoginFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        // Java 1.8 stream API used here
        Cookie loginCookie = Arrays.stream(req.getCookies()).filter(c -> c.getName()
                .equals("MY_SESSION_COOKIE")).findAny().orElse(null);

        // if we don't have the user already in session, check our cookie MY_SESSION_COOKIE
        if (req.getSession().getAttribute("currentUser") == null) {
            // if the cookie is not present, add it
            if (loginCookie == null) {
                loginCookie = new Cookie("MY_SESSION_COOKIE", UUID.randomUUID().toString());
                // Store that cookie only for our app. You can store it under "/", 
                // if you wish to cover all webapps on the server, but the same datastore
                // needs to be available for all webapps.
                loginCookie.setPath(req.getContextPath());
                loginCookie.setMaxAge(DAYS.toSeconds(1)); // valid for one day, choose your value
                resp.addCookie(loginCookie);
            }
            // if we have our cookie, check it
            else {
                String userId = datastore.getLoggedUserForToken(loginCookie.getValue());
                // the datastore returned null, if it does not know the token, or 
                // if the token is expired
                req.getSession().setAttribute("currentUser", userId);
            }
        }
        else {
            if (loginCookie != null)
                datastore.updateTokenLastActivity(loginCookie.getValue());
        }

        // if we still don't have the userId, forward to login
        if (req.getSession().getAttribute("currentUser") == null)
            resp.sendRedirect("login.jsp");
        // else return the requested resource
        else
            chain.doFilter(request, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }

}