`
阅读更多

转载自:http://stackoverflow.com/questions/16099752/session-or-cookie-confusion

[PART 1] : SESSION OBJECT

HTTP-request are processed separately, so in order to keep information between each request (for instance, information about the user), a session object has to be created on server-side.

Some websites doesn't need a session at all. A website where users can't modify any content won't have to manage a session (for instance, an online CV). You won't need any cookie or session on such a website.

Create a session :

In a servlet, use the method request.getSession(true) from the HttpServletRequest object to create a new HttpSession object. Note that if you use request.getSession(false)null will be returned if the session has not already been created. Look at this answer for more details.

Set / Get attributes :

The purpose of a session is to keep information on server-side between each request. For instance, keeping the user's name :

session.setAttribute("name","MAGLEFF");
// Cast
String name = (String) session.getAttribute("name");

Destroy a session :

A session will be automatically destroyed if kept inactive too much time. Look at this answer for more details. But you can force manually the session to be destroyed, in the case of a logout action for example :

HttpSession session = request.getSession(true); 
session.invalidate();

 [PART 2] : So... join the dark side, we have COOKIES ?

There comes the cookies.

JSESSIONID :

JSESSIONID cookie is created on the user's computer each time a session is created withrequest.getSession(). Why ? Because each session created on server side has an ID. You can't acces another user's session, unless you don't have the right ID. This ID is kept in JSESSIONID cookie, and allow the user to find his information. Look at this answer for more details !

When does a JSESSIONID is deleted ?

JSESSIONID doesn't have an expiration date : it's a session cookie. As all session cookies, it will be deleted when the broswer is closed. If you use the basic JSESSIONID mechanism, then the session will become unreachable after you close and re-open the browser, because JSESSIONID cookie is deleted.

Note that the session is unreachable by the client, but is still running on server-side. Setting aMaxInactiveInterval allows the server to automatically invalidate the session when it has been inactive for too long.

Evil destruction of JSESSIONID

Just for fun, one day I found this code on a project. It was used to invalidate the session by deleting the JSESSIONID cookie with javascript :

<SCRIPT language="JavaScript" type="text/javascript">

    function delete_cookie( check_name ) {
        // first we'll split this cookie up into name/value pairs
        // note: document.cookie only returns name=value, not the other components
        var a_all_cookies = document.cookie.split( ';' );
        var a_temp_cookie = '';
        var cookie_name = '';
        var cookie_value = '';
        var b_cookie_found = false; // set boolean t/f default f
        // var check_name = 'JSESSIONID';
        var path = null;

        for ( i = 0; i < a_all_cookies.length; i++ )
        {
            // now we'll split apart each name=value pair
            a_temp_cookie = a_all_cookies[i].split( '=' );
            // and trim left/right whitespace while we're at it
            cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
            // alert (cookie_name);

            // if the extracted name matches passed check_name
            if ( cookie_name.indexOf(check_name) > -1 )
            {
                b_cookie_found = true;
                // we need to handle case where cookie has no value but exists (no = sign, that is):
                if ( a_temp_cookie.length > 1 )
                {
                    cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
                    document.cookie = cookie_name + "=" + cookie_value +
                    ";path=/" +
                    ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
                    // alert("cookie deleted " + cookie_name);
                }
            }
            a_temp_cookie = null;
            cookie_name = '';
        }
        return true;
    }
    // DESTROY
    delete_cookie("JSESSIONID");

</SCRIPT>

 Give another look to this answer. With javascript, JSESSIONID can be red, modified, etc. and the session lost, or hijacked.

[PART 3] : KEEPING A SESSION AFTER CLOSING YOUR BROWSER

After closed and re-opened the browser and their accounts are still signed in. But some websites, cannot do like that. I'm confused that it's considered session or cookie??

It's cookie.

We saw that when the JSESSIONID session cookie has been deleted by the web browser, the session object on server-side is lost. There is no way to access it again without the right ID.

If I want my website to be signed in like that, do I have to set session.setMaxInactiveInterval() or cookie.setMaxAge()?

We also saw that session.setMaxInactiveInterval() was to prevent from running a lost session indefinitely. JSESSIONID cookie cookie.setMaxAge() won't get us anywhere either.

Use a persistent cookie with the session Id :

I came to this solution after reading the following topics :

The main idea is to register the user's session in a Map, put into the servlet context. Each time a session is created, it is added to the Map with the JSESSIONID value for key; A persistent cookie is also created to memorize the JSESSIONID value, in order to find the session after the JSESSIONID cookie has been destroyed.

When you close the web browser, JSESSIONID is destroyed. But all the HttpSession objects adress have been kept into a Map on server-side, and you can access the right session with the value saved into the persistent cookie.

First, add two listeners in your web.xml deployment descriptor.

<listener>
    <listener-class>
        fr.hbonjour.strutsapp.listeners.CustomServletContextListener
    </listener-class>
</listener>

<listener>
    <listener-class>
        fr.hbonjour.strutsapp.listeners.CustomHttpSessionListener
    </listener-class>
</listener>

 The CustomServletContextListener creates a map at context initialization. This map will register all the sessions created by the user on this application.

/**
 * 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...
    }
}

 The CustomHttpSessionListener will put the session into the activeUsers map when it is created.

/**
 * 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());
    }

}

 Use a basic form to test a user authentification by name/password. This login.jsp form is meant for test only.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title><bean:message key="formulaire1Title" /></title>
    </head>
    <body>
        <form action="login.go" method="get">
            <input type="text" name="username" />
            <input type="password" name="password" />
            <input type="submit" />
        </form>
    </body>
</html>

 There we go. This java servlet is forwarding to a login page when the user is not in session, and to another page when he is. It is only meant for testing the persistent session!

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 );

    }

 The MY_SESSION_COOKIE cookie save the value of the JSESSIONID cookie. When the JSESSIONID cookie is destroyed, the MY_SESSION_COOKIE is still there with the session ID.

JSESSIONID is gone with the web browser session, but we chose to use a persistent and simple cookie, along with a map of all active sessions put into the application context. The persistent cookie allow us to find the right session in the map.

Don't forget these useful methods made by BalusC to add/get/remove cookies :

/**
 * 
 * @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);
}

}

 The last solution was tested with glassfish on localhost, with chrome for webbrowser, on windows. It only depends on a single cookie, and you don't need a database. But actually, I don't know what are the limits of such a mechanism. I only spent the night coming to this solution, without knowing if it will be a good or a bad one.

分享到:
评论

相关推荐

    session and cookies.ppt

    在ASP.NET中,Session和Cookies是两种常见的用户状态管理机制,它们用来跟踪用户在网站上的行为和信息。本文将深入探讨这两个概念以及相关的知识点。 首先,让我们了解什么是Session。Session是一种服务器端的状态...

    ajax+ASP 调试ASP语句小程序,可帮助调试asp,如查看session cookies appliation

    本文将详细介绍一款基于Ajax和ASP的小程序,它专门用于调试ASP语句,特别是涉及到session、cookies和application对象的调试。 **一、调试ASP语句的重要性** 调试是编程过程中的关键环节,对于ASP开发者来说,能够...

    Laravel开发-laravel-memory-auth-provider

    6. **Session and Cookies**: Laravel使用`Session`来保持用户的状态,即使在多个请求之间。内存认证仍然会利用`Session`来跟踪已登录的用户,但用户信息本身是在内存中存储的。 在实际使用`laravel-memory-auth-...

    session asp.net and so on!

    Session是一个服务器端的状态管理工具,它为每个用户创建一个唯一的标识(SessionID),这个标识被存储在用户的浏览器cookies中。每当用户请求一个新的页面时,服务器会根据SessionID找到与之关联的数据。 二、...

    HttpModule检验Session值

    在`Context_BeginRequest`事件处理程序中,我们可以访问`HttpContext.Current.Session`和`HttpContext.Current.Request.Cookies`来获取和检查Session和Cookie。如果Session为空或Cookie过期,我们可以采取相应的措施...

    cookieAndsession.zip

    在IT行业中,尤其是在Web开发领域,Cookie和Session是两种非常重要的技术,用于管理用户状态和保持用户会话。本文将详细探讨Cookie与Session的工作原理、优缺点以及它们在Node.js环境中的应用。 **Cookie** Cookie...

    基于c#实现cookie和session的登陆技术

    在IT行业中,网络应用程序的用户认证是至关重要的。本文将深入探讨如何在C#环境中,特别是在Visual Studio 2005环境下,利用Cookie和...压缩包中的CookieAndSession项目正是这样一个实践示例,供学习者参考和实践。

    Session.docx

    - **AJAX概述**:AJAX(Asynchronous JavaScript and XML)是一种在不刷新整个页面的情况下,与服务器交换数据并更新部分网页的技术。 - **异步交互**:与同步请求不同,AJAX请求可以在等待服务器响应的同时,继续...

    Bulletproof SSL and TLS,PDF , Ivan Ristic

    Understanding HTTP Cookies 117 Cookie Manipulation Attacks 118 Impact 122 Mitigation 122 v SSL Stripping 123 MITM Certificates 125 Certificate Warnings 126 Why So Many Invalid Certificates? 127 ...

    面试中会遇到的技术问题

    #### Session与Cookies的基础概念及其替代方案 **Session与Cookies的概念:** 在Web开发中,Session 和 Cookies 是两种常用的状态管理技术,用于维护用户的会话状态。 - **Session**:一种服务器端的技术,用于...

    在Python的Django框架的视图中使用Session的方法

    与Cookies不同的是,Session数据通常存储在服务器端,而Cookies数据则存储在客户端浏览器上。 #### Django Session机制 Django提供了内置的Session支持,使得在应用程序中实现用户状态跟踪变得简单。Django的...

    Ajax + PHP session制作购物车

    当一个用户访问网站时,PHP生成唯一的session id,并通过cookies或URL传递,确保用户可以被识别。在PHP中,使用session_start()函数开始会话,并通过$_SESSION超全局数组存储数据。 接下来,购物车是电子商务网站的...

    ASP.NET 4 Unleashed(part 1)

    Maintain state with cookies, cookieless session state, and profiles Localize, configure, package, and deploy ASP.NET applications Use the ASP.NET MVC Framework to improve agility, testability, speed ...

    jwts-not-safe-e-book.pdf

    - **Client-Side Storage:** Cookies or local storage can be used to store session tokens on the client side. This approach is simple but raises security concerns since data stored on the client can be...

    IntraWeb v14.0.23 Ultimate for RAD Studio XE-XE5 (x32+x64)

    Bug fix: When deploying the application as ISAPI, session tracking without cookies would fail Bug fix: When a IW application was compiled with runtime packages, TIWAppInfo.GetAppFullFileName was ...

    ChromeDriver v2.24 for windows linux and mac (2016-09-09)

    Resolved issue 1310: ChromeDriver hangs (and times out) when inspecting inactive background pages [['OS-All', 'Pri-2']] Resolved issue 824: ChromeDriver creates two cookies when the cookie to add ...

    android与asp.net服务端共享session的方法详解

    最近因为工作的需要,要实现一个功能,就是需要通过发送短信进行注册,现在想把短信验证码放到服务器的session值中,当客户端收到短信并提交短信码时由asp.net服务端进行判断,那么如何共享这个session那么需要在...

    next-iron-session::hammer_and_wrench:Next.js无状态会话实用程序,使用签名和加密的cookie来存储数据

    :hammer_and_wrench: Next.js和Express(连接中间件)无状态会话实用程序,使用签名和加密的cookie来存储数据 这个 , 和后端实用程序允许您创建一个会话,然后通过签名和加密的印章将其存储在浏览器cookie中。 这...

Global site tag (gtag.js) - Google Analytics