Cookie 与 Session

一、Cookie 详解

1.Cookie 是什么?

Cookie,是某些网站为了辨别用户身份,进行session跟踪而储存在用户本地终端上的数据,由用户客户端计算机暂时或永久保存的信息;

2.为什么使用Cookie?

由于 web 程序是使用HTTP传输协议的,而HTTP协议属于无状态的协议,对于事务处理没有记忆能力;因此当后续处理需要前面的信息时就需要重新上传,这样就会导致每次连接传送的数据量增大了;
Cookie的出现就可以解决这一问题
原理
第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器将其保存在本地,当该用户发送第二次请求时 就会把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是那个了;
简单来讲cookie的工作原理就是
给每个用户发放一个通行证,这样服务器就能通过通行证确认用户身份了;

3.Cookie 产生时间

  • Cookie 的使用首先取决于用户(原因:浏览器可以禁用Cookie,同时服务端也可以不set-cookie
  • Cookie的两种保存方式:其1为浏览器将Cookie保存在内存中,其2为保存在客户端的硬盘上,之后每次HTTP请求浏览器都会将Cookie 发送给服务端;

4.Cookie 生存周期

Cookie 在生成时就会被指定一个Expire值,这就是Cookie的生存周期,在这个周期内Cookie有效,超出周期就会被清除;

5.Cookie 缺陷

  • 数量受限制

表现在

一个浏览器能创建的 Cookie 数量最多不超过300个,且每个不能超过4KB,每个web站点能设置的Cookie 总数不能超过20个;

  • 安全性得不到保障

表现在:存在跨站点脚本攻击

  • 浏览器可以设置禁用Cookie

6.Cookie 使用场景

基于Cookie 的缺陷,因此一般使用在:

  • 对安全性要求不高;
  • 不需要存储大量的数据;
  • 主要用于客户端与服务器之间的状态保持;

二、Session 详解

1.什么是 Session

Session 也称为会话机制,那什么是会话呢?
会话的本质:就是一个"哈希表", 存储了一些键值对结构,其中 key 就是令牌的 ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计);
sessionId 和 token 就可以理解成是同一个东西的不同叫法;

流程为

  • 当用户登陆的时候, 服务器在 Session 中新增一个新记录, 并把 sessionId / token 返回给客户端(例如通过 HTTP 响应中的 Set-Cookie 字段返回);
  • 客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId/ token (例如通过 HTTP 请求中的 Cookie 字段带上);
  • 服务器收到请求之后, 根据请求中的 sessionId / tokenSession 信息中获取到对应的用户信息, 再进行后续操作;

2.Session 生命周期

根据需求设定,一般为半个小时(当你登陆一个服务器时,服务器返回给你一个sessionID ,登陆成功后的半个小时之内没有对该服务器进行任何的HTTP请求,半个小时之后进行一次HTTP请求,就会提示你重新登陆);


三、涉及核心方法

HttpServletRequest 类中的相关方法

方法描述
HttpSession getSession()在服务器中获取会话,参数为true,当会话不存在时,新建会话;参数为false时,会话不存在返回null
Cookie[] getCookies()返回一个数组,包含客户端发送请求的所有Cookie对象,会自动把Cookie中的格式解析成键值对

HttpServletResponse 类中的相关方法

方法描述
void addCookie(Cookie cookie)把指定的Cookie 添加到响应中

HttpSession 类中的相关方法

方法描述
Object getAttribute(String name)该方法返回在该 session 会话中具有指定名称的对象,没有返回null
void setAttribute(String name, Object value)该方法使用指定的名称绑定一个对象到该 session 会话
boolean isNew()判定当前是否是新创建出的会话

Cookie 类中的相关方法

方法描述
String getName()返回 cookie 的名称 ,名称在创建后不能改变,(这个值是 Set-Cooke 字段设置给浏览器的)
String getValue()获取与 cookie 关联的值
void setValue(String newValue)设置与 cookie 关联的值

四、代码示例(用户登陆)

简单实现用户登陆,登陆成功后允许访问敏感资源

前端代码:请求方法为 post

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>

    <h3>用户登陆</h3>
    <form action="login" method="post">
    <input type="text" name="username" placeholder="请输入用户名">
    <br>
    <input type="text" name="password" placeholder="请输入密码">
    <br>
    <input type="submit" value="提交">
</form>
</body>

</html>

后端代码

  • 创建一个 LoginServlet
package 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 LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //body:username=xxx&password=xxx
        //登陆成功:跳转到request.html,此时允许访问敏感资源(/sensitive)
        //登陆失败:返回错误信息,此时不允许访问敏感资源
        String username = req.getParameter("username");
        String password = req.getParameter("password");


        //模拟数据库进行账号密码登陆
        if("abc".equals(username) && "123".equals(password)){
            //登陆成功
            //为登陆成功的用户创建一个session

            //tomcat启动时维护了一个数据结Map<String,Session>
            //用来保存多个用户的会话信息,键为sessionID的值(随机字符串)
            //获取当前请求的session,如果没有获取到就重新创建一个放在Map结构中
            HttpSession session =req.getSession(true);
            //session对象本身也是一个Map结构,可以保存多组键值对的信息
            session.setAttribute("u","username");
            //以上代码会设置一个set-cookie,jsessionid=随机字符串
            //跳转到登录后的页面
            resp.sendRedirect("request.html");
        }else{
            //登陆失败,返回错误信息
            resp.setContentType("text/html;charset=utf-8");
            resp.getWriter().println("登陆失败");
        }

    }
}

  • 创建一个 SensitiveServlet
package 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("/sensitive")
public class SensitiveServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        //获取当次请求的session(此时可能登陆,也可能没有登陆)
        //如果没有获取到,就返回null
        HttpSession session = req.getSession(false);
        if(session != null){
            //session 不为空
            String username = (String) session.getAttribute("u");
            if(username != null){
                //session设置的数据也不为空
                resp.getWriter().println("用户已登陆,允许访问");
                return;
            }
        }

            resp.getWriter().println("用户未登录,不允许访问");
    }
}

运行 tomcat,三种情况如下所示

  • (1)当没有登陆时就访问sensitive,此时出现如下界面所示内容:

在这里插入图片描述

  • (2)当访问登陆页面时,输入错误的账号密码时,如下所示:
    在这里插入图片描述
    当点击提交时,也面会发生跳转,但会显示如下登陆失败页面:
    在这里插入图片描述
  • (3)只有输入正确的账号密码时,页面才会跳转到request.html 中,显示:
    在这里插入图片描述

服务器会给当前用户设置一个set-cookie,jsessionid=随机字符串:
在这里插入图片描述

五、小结

  • Cookie 是客户端的机制,它可以存储在浏览器,也可以存储在本地;Session 是服务器端的机制,只能存储在服务器;
  • session能够存储任意的Java对象,但cookie只能存储string类型的对象;
  • session占用服务器性能,session越多就会增加服务器压力;
  • cookie没有session安全性高;
  • 单个cookie保存的数据不能超过4KB,而session的大小限制与服务器本身的内存大小相关;
  • 7
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值