cookie和session

----其实这是个基本的问题,奈何自己对他们了解不深,特开此贴,加深理解。
Q1:为什么要有cookie和session?
A1:因为http是个无状态协议,也就是说在一次会话中我做了啥事,我不会记住,所以得有个地方记录一下这次会话的状态,而cookie和session就是来记录会话状态的技术。
那么先来聊聊cookie。
Q2:cookie是由谁产生?什么时候产生?保存在哪里?
A2:cookie是由服务器产生,保存在客户端的一种信息载体。这个载体中存放的是会话状态的信息。只要cookie没有被清空,或者说cookie没有失效,那么保存的会话状态信息就有效。
用户在提交一次请求后,由服务器生成cookie,并将其封装在响应头中,以响应的形式发送给客户端。客户端在接收到这个响应后,将cookie保存在客户端,当客户端再次发送同类请求后,在请求中会携带保存在客户端的cookie数据,发送到服务端,由服务器进行会话跟踪。
Q3:为什么要有session?
A3:因为你cookie是保存在客户端是不安全的,比如说你的用户名或者密码都在cookie中,很可能会被别人盗取,得了吧,你每次也别拿着你身份信息了,你只需要拿个身份证号码(JSESSIONID)就行了,你的身份信息我给你保存到服务器上了,这样在一个会话中,我(服务器)就知道你是谁了,提高了安全性。
Q4:session工作的原理是什么?
(1)写入session列表
当前应用中的session是以map的形式进行管理的,这个map称为sessionMap,该map的key是一个32位长度的随机字符串,称之为JSessionID,value则是一个对象的引用。
当用户第一次提交请求时,服务端会调用getSession()方法生成一个Map.Entry对象,key为一个32位长度的随机字符串,value就是一个HttpSession对象。所以,你就可以认为你的会话中的信息就保存在一个map中。
(2)在将session信息保存到map中后,系统还自动将“JESSIONID”作为name,将32位长度的随机字符串作为value,以cookie的形式放到响应头中,并随着响应发送到客户端。
(3)当客户端接收到这个cookie后会将他保存到浏览器中的缓存中,即当客户端浏览器不关闭,浏览器中的缓存就不会失效。当用户第二次提交请求时会携带上缓存中的cookie,伴随着请求中的头部信息一起发送给服务端。

Q4:你老是说session依赖cookie你怎么证明呢?
A4:其实我也是一直听别人说session依赖cookie,session依赖cookie,session依赖cookie,那么终于给证明了,其实很简单,你debug进去就行了,豁然开朗的感觉。
上代码

    @RequestMapping("/setsession")
    public String setsession(HttpServletRequest request,HttpServletResponse response){
        String username=request.getParameter("username");
        request.setAttribute("username",username);

       HttpSession session= request.getSession();
       session.setAttribute("user",username);
        return "some: "+username;
    }
    看到.getSession()方法了吧
    getSession()
      getSession(true);
       HttpSession getSession(boolean create)
        getSession(create)
         doGetSession(create)
    protected Session doGetSession(boolean create) {

        // There cannot be a session if no context has been assigned yet
        Context context = getContext();
        if (context == null) {
            return (null);
        }

        // Return the current session if it exists and is valid
        if ((session != null) && !session.isValid()) {
            session = null;
        }
        if (session != null) {
            return (session);
        }

        // Return the requested session if it exists and is valid
        Manager manager = context.getManager();
        if (manager == null) {
            return (null);      // Sessions are not supported
        }
        if (requestedSessionId != null) {
            try {
                session = manager.findSession(requestedSessionId);
            } catch (IOException e) {
                session = null;
            }
            if ((session != null) && !session.isValid()) {
                session = null;
            }
            if (session != null) {
                session.access();
                return (session);
            }
        }

        // Create a new session if requested and the response is not committed
        if (!create) {
            return (null);
        }
        if (response != null
                && context.getServletContext()
                        .getEffectiveSessionTrackingModes()
                        .contains(SessionTrackingMode.COOKIE)
                && response.getResponse().isCommitted()) {
            throw new IllegalStateException(
                    sm.getString("coyoteRequest.sessionCreateCommitted"));
        }

        // Re-use session IDs provided by the client in very limited
        // circumstances.
        String sessionId = getRequestedSessionId();
        if (requestedSessionSSL) {
            // If the session ID has been obtained from the SSL handshake then
            // use it.
        } else if (("/".equals(context.getSessionCookiePath())
                && isRequestedSessionIdFromCookie())) {
            /* This is the common(ish) use case: using the same session ID with
             * multiple web applications on the same host. Typically this is
             * used by Portlet implementations. It only works if sessions are
             * tracked via cookies. The cookie must have a path of "/" else it
             * won't be provided for requests to all web applications.
             *
             * Any session ID provided by the client should be for a session
             * that already exists somewhere on the host. Check if the context
             * is configured for this to be confirmed.
             */
            if (context.getValidateClientProvidedNewSessionId()) {
                boolean found = false;
                for (Container container : getHost().findChildren()) {
                    Manager m = ((Context) container).getManager();
                    if (m != null) {
                        try {
                            if (m.findSession(sessionId) != null) {
                                found = true;
                                break;
                            }
                        } catch (IOException e) {
                            // Ignore. Problems with this manager will be
                            // handled elsewhere.
                        }
                    }
                }
                if (!found) {
                    sessionId = null;
                }
            }
        } else {
            sessionId = null;
        }
        session = manager.createSession(sessionId);

        // Creating a new session cookie based on that session
        if (session != null
                && context.getServletContext()
                        .getEffectiveSessionTrackingModes()
                        .contains(SessionTrackingMode.COOKIE)) {
            Cookie cookie =
                ***ApplicationSessionCookieConfig.createSessionCookie(
                        context, session.getIdInternal(), isSecure());
            response.addSessionCookieInternal(cookie);***
        }

        if (session == null) {
            return null;
        }

        session.access();
        return session;
    }
=============================================
  ApplicationSessionCookieConfig.createSessionCookie(
                        context, session.getIdInternal(), isSecure());
response.addSessionCookieInternal(cookie)
==================================================

doGetSession中有上面这个代码,这个就是session中利用了cookie的铁证。

Q5:我如果客户端禁用了cookie,就是我客户端不能保存你服务端给我的身份证了,并且我也不能携带这些信息了。这时候用session机制该怎么办?
A5:佛说,URL重写。至于什么是URL重写你可以谷歌和问度娘。


  
         
        
        
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值