【图解HTTP读书笔记】第八章:Session 和 Cookie工作原理

Cookie工作原理

在这里插入图片描述

Cookie演示

我们启动服务器,演示一下Cookie 的效果:
服务器:
在这里插入图片描述
客户端:(第一次设置 Cookie)
在这里插入图片描述
第二次就会自己加上Cookie信息,在这里存的就是用户的信息:
在这里插入图片描述
我们在看看服务器:
在这里插入图片描述
我们还可以通过Fiddler抓包看看我们构造的响应和请求:在这里插入图片描述
再次理解Cookie:Cookie是可以有多个的也不是一成不变的,比如我们演示一个多次访问cookieTime,每次都获取到不同的时间戳作为Cookie。
第一次访问:
在这里插入图片描述
第二次访问:
在这里插入图片描述
在这里只是修改了 time 这个cookie, user 还是登录用户的信息,是不收影响的。

如何使用cookie 完成一次登录过程,我们得看看下边这个代码是如何实现,不仅仅是浏览器,服务器也要做出相应的逻辑实现。

V3版本http 服务器

主要工作:
1、支持返回一个静态的 html 文件
2、解析处理 cookie(把 cookie处理成键值对结构)
3、解析处理 body (把body 中的数据处理成键值对结构)
4、实现完整的登录功能(session 的简单实现)
在这里我说一下主要代码:

private void doPost(HttpRequest request, HttpResponse response) {
    
    
        // 2. 实现 /login 的处理
        if (request.getUrl().startsWith("/login")) {
    
    
            // 读取用户提交的用户名和密码
            String userName = request.getParameter("username");
            String password = request.getParameter("password");
//            System.out.println("userName: " + userName);
//            System.out.println("password: " + password);
            // 登陆逻辑就需要验证用户名密码是否正确.
            // 此处为了简单, 咱们把用户名和密码在代码中写死了.
            // 更科学的处理方式, 应该是从数据库中读取用户名对应的密码, 校验密码是否一致.
            if ("fwh".equals(userName) && "123".equals(password)) {
    
    
                // 登陆成功
                response.setStatus(200);
                response.setMessage("OK");
                response.setHeader("Content-Type", "text/html; charset=utf-8");
                // 原来登陆成功, 是给浏览器写了一个 cookie, cookie 中保存的是用户的用户名.
                // response.setHeader("Set-Cookie", "userName=" + userName);

                // 现有的对于登陆成功的处理. 给这次登陆的用户分配了一个 session
                // (在 hash 中新增了一个键值对), key 是随机生成的. value 就是用户的身份信息
                // 身份信息保存在服务器中, 此时也就不再有泄露的问题了
                // 给浏览器返回的 Cookie 中只需要包含 sessionId 即可
                String sessionId = UUID.randomUUID().toString();
                User user = new User();
                user.userName = "fwh";
                user.age = 20;
                user.school = "邮电";
                sessions.put(sessionId, user);
                response.setHeader("Set-Cookie", "sessionId=" + sessionId);

                response.writeBody("<html>");
                response.writeBody("<div>欢迎您! " + userName + "</div>");
                response.writeBody("</html>");
            } else {
    
    
                // 登陆失败
                response.setStatus(403);
                response.setMessage("Forbidden");
                response.setHeader("Content-Type", "text/html; charset=utf-8");
                response.writeBody("<html>");
                response.writeBody("<div>登陆失败</div>");
                response.writeBody("</html>");
            }
        }
    }

session 工作原理

在这里插入图片描述

response.setHeader("Set-Cookie", "userName=" + userName);

如果我们用这行代码,借助 Cookie来实现登录保持功能,这样做是不太好的,用户信息在 Cookie中,每次数据传输都要把这个 Cookie 再次发给服务器,这就意味着 Cookie 中的信息很容易泄露,甚至可以伪造,绕开登录~~所以我们就需要session了!

在服务器登录成功时,把用户信息保存在一个 hash 表中(value),同时生成一个 key(这个key 是一个唯一的字符串),sessionId,最终把 sessionId 写会到 cookie 中就好了。后续访问页面的时候,Cookie 中的内容就是 sessionId,sessionId是一个没有规律的字符串,提高了安全性。服务器可以通过 sessionId 进一步找到用户的相关信息。

String sessionId = UUID.randomUUID().toString();

这行代码就会生成一个随机的字符串,每次1调用都会生成不同的。
刚开始是没有的,响应通过 set-Cookie 来保存:
在这里插入图片描述
接下来访问就可以获得:
在这里插入图片描述
通常session 是要搭配一个 过期机制,来记录线程何时创建,何时过期,如果过期也需要你重新登录,不同的网站它自己设定的过期时间也是不同的。

Cookie 和 session 的关系

  1. 都是为了实现客户端与服务端交互而产出
  2. Cookie是保存在客户端,缺点易伪造、不安全
  3. Session是保存在服务端,会消耗服务器资源
  4. Session实现有两种方式:Cookie和URL重写

参考:深入理解HTTP协议

Session 管理及Cookie 应用

基于表单认证的标准规范尚未有定论,一般会使用Cookie 来管理Session(会话)。

在这里插入图片描述

  • 步骤一:客户端把用户ID 和密码等登录信息放入报文的实体部分,通常是以POST 方法把请求发送给服务器。而这时,会使用HTTPS 通信来进行HTML 表单画面的显示和用户输入数据的发送。
  • 步骤二:服务器会发放用以识别用户的Session ID。通过验证从客户端发送过来的登录信息进行身份认证,然后把用户的认证状态与Session ID 绑定后记录在服务器端。
  • 步骤三:客户端接收到从服务器端发来的Session ID 后,会将其作为Cookie 保存在本地。下次向服务器发送请求时,浏览器会自动发送Cookie,所以Session ID 也随之发送到服务器。服务端可通过验证接收到的Session ID 识别用户和其认证状态。

另外,不仅基于表单认证的登录信息及认证过程都无标准化的方法,服务器端应如何保存用户提交的密码等登录信息等也没有标准化。

参考:《图解HTTP》

猜你喜欢

转载自blog.csdn.net/weixin_45532227/article/details/113050574