Cookie和Session

Posted 无赖H4

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie和Session相关的知识,希望对你有一定的参考价值。

Cookie和Session


HTTP协议是一种无状态的协议,但是在现实生活中希望出现会话管理,所以出现了cookie和session机制。
应用场景:
例如:登录,注册…
需要保持一段时间的在线状态

Cookie和Session

cookie

一种在浏览器中解决的方案,将登录认证的信息保存在本地浏览器中,后面发起的http请求,都会自动携带该信息,达到认证用户,保持用户在线状态。

Session

如果将敏感信息放在本地浏览器中,会出现安全问题,一旦cookie泄露会有安全风险。所以引出session,将用户的敏感信息放在服务器中,生成sessionid保存在浏览器中,达到保持状态的操作。

流程

例子

1、用户输入/login.html后进入进行登录。
2、将登录信息通过post将form表单发送到Login.java,因为是第一次,之前没有这个用户名的session兑现,所以创建一个session兑现,并将cookie:session-id返回浏览器。
3、浏览器保存好cookie,后面每次调用book/*,都会携带cookie,并修改用户空间的值。
4、最后可以通过访问用户空间,查看数据

login.html

<!DOCTYPE html>
<html lang="zh-hans">
<head>
  <meta charset="UTF-8">
  <title>登录</title>
</head>
<body>
  <form method="post" action="/login">
    <input type="text" name="username">
    <button type="submit">登录</button>
  </form>
</body>
</html

Login.java

package cookie_session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

@WebServlet("/login")
public class Login extends HttpServlet 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        req.setCharacterEncoding("utf-8");
        String username = req.getParameter("username");

        // 没有真正的验证
        HttpSession session = req.getSession();
        // 实际中做了两个事情
        // 1. 种了 Cookie
        // 2. 保存好了 Session
        session.setAttribute("current_user", username);

        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/plain");
        resp.getWriter().println("登录成功");
    


Book.java

package cookie_session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

// /book/1
// /book/2
// /book/3
@WebServlet("/book/*")
public class Book extends HttpServlet 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        String servletPath = req.getRequestURI();
        int i = servletPath.lastIndexOf('/');
        int no = Integer.parseInt(servletPath.substring(i + 1));

        // 从 session 中获取谁在买书
        // 1. 保证浏览器发请求携带着 Cookie
        // 2. Session 中有数据
        HttpSession session = req.getSession();
        String username = (String) session.getAttribute("current_user");

        int[] intArray = History.map.get(username);
        if (intArray == null) 
            intArray = new int[3];
            History.map.put(username, intArray);
        

        intArray[no - 1]++;
        for (Map.Entry<String, int[]> entry : History.map.entrySet()) 
            System.out.println("购买人: " + entry.getKey());
            int[] array = entry.getValue();
            for (int j = 0; j < 3; j++) 
                System.out.printf("购买了 %d 书 %d 次\\n", j + 1, array[j]);
            
        

        resp.setContentType("text/plain");
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().println("购买成功");
    


Userspace.java

package cookie_session;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/userspace")
public class Userspace extends HttpServlet 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        // 我们需要先确定现在是哪个用户在访问这个资源
        HttpSession session = req.getSession();
        String username = (String) session.getAttribute("current_user");
        if (username == null) 
            // 用户没有带卡(没有Cookie)
            // 店里账本丢了(没有Session)
            // 我们视为没有登录
            resp.setContentType("text/plain");
            resp.setCharacterEncoding("utf-8");
            resp.getWriter().println("您没有登录,没有资格查看购买记录");
            return;
        

        // 登录过了 (username != null)
        int[] array = History.map.get(username);
        if (array == null) 
            resp.setContentType("text/plain");
            resp.setCharacterEncoding("utf-8");
            resp.getWriter().println(username + "用户,您没有购买过书籍");
            return;
        
        resp.setContentType("text/plain");
        resp.setCharacterEncoding("utf-8");
        PrintWriter writer = resp.getWriter();
        for (int i = 0; i < 3; i++) 
            writer.printf("%d 书买了 %d 次\\n", i + 1, array[i]);
        
    

History.java

package cookie_session;

import java.util.HashMap;
import java.util.Map;

public class History 
    // key: 用户名
    // value: int[3]
    // [0]: book1 的次数
    // [1]: book2 的次数
    // [2]: book3 的次数
    // TODO: 修复线程安全风险
    public final static Map<String, int[]> map = new HashMap<>();


需要注意的是:
HttpSession session = req.getSession();
如果之前没有session对象,那么会创建一个对象,否则返回之前的对象。

cookie与HTTP

cookie和http协议有关
响应:种cookie,Header:Set-cookie Value: name=value
种下的cookie: Cookie:XXXXXXXXX;
我们可以借助开发者工具查看
session和HTTP协议“无关”,通常用cookie传递一个session-id
cookie和session都可以独立,但是cookie+session才是最佳状态
cookie中有一个关键的属性,过期时间(默认是会话时间(关闭浏览器就没有了))
cookie.setMaxAge(60);
可以通过设置,改变时间

Cookie和Session的区别

严格说,区别是对同一种事物而言,对于cookie和session是一种相互配合的机制。
因为http是一种无状态的协议,现实生活中需要一种会话管理来解决问题,所以产生了cookie和session机制。(会话管理)cookie和session最重要的引用场景就是(注册,登录,注销)。cookie保存在浏览器中,session存在服务器中,每次发起请求时需要携带cookie,所以cookie大小有限制,cookie的值可以访问,但无法轻易访问会话值,session相对安全。

以上是关于Cookie和Session的主要内容,如果未能解决你的问题,请参考以下文章

Python爬虫番外篇之Cookie和Session

Cookie和Session的那些事儿

session和cookie

cookie窃取和session劫持

cookie和session的比较

cookie和session的区别