Cookie和Session

简介: Cookie和Session

今天我们来认识一下Session

🧊1.回忆Cookie


🧊2.认识Session(会话)


🧊1.利用Session模拟实现登录功能


🧊2.登录逻辑的固定套路


🧊3.Cookie和Session区别


1.回忆Cookie

我们之前已经学习过了cookie机制

Cookie是浏览器在本地存储数据的一种机制

1.cookie从哪里来

cookie是从服务器来的

服务器在响应中会带有Set-Cookie字段,通过这个字段就可以把要把保存在浏览器本地的数据给返回回去

2.cookie到哪里去

后续浏览器访问服务器的时候,会把当前本地所有的cookie都通过http请求给带过去


3.cookie有啥用

最典型的应用就是用Cookie保存当前用户的登录状态


2.认识Session(会话)


而在Cookie保存用户身份标识这类的应用场景,身份标识如何分配,以及身份信息具体如何存储,都是需要服务器的支持的

那么这个时候用啥来实现用户区分呢?

用Session(会话)

Session既是服务器用来实现用户身份区分的一种机制,通常和Cookie配合使用

Session是给当前的用户分配一个sessionId,同时记录当前用户的身份信息

sessionId就会被返回浏览器的cookie中,后续浏览器访问服务器就会带着这个sessionId,从而让服务器识别当前用户的身份

会话的本质就是一个 “哈希表”, 存储了一些键值对结构. key 就是令牌ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).

Servlet 的 Session 默认是保存在内存中的. 如果重启服务器则 Session 数据就会丢失.


我们来画图理解一下吧


0ae56b90d6a2474eaf207691a16281c8.png

1.当用户登陆的时候, 服务器在 Session 中新增一个新记录, 并把 sessionId 返回给客户端. (例如通过 HTTP 响应中的 Set-Cookie 字段返回).

2.客户端后续再给服务器发送请求的时候, 需要在请求中带上 sessionId (例如通过 HTTP 请求中的 Cookie 字段带上).

服务器收到请求之后, 根据请求中的 sessionId 在 Session 信息中获取到对应的用户信息,

再进行后续操作.


1.下面来认识一下Session的方法


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


getSession有一个参数,boolean类型的,

如果参数为false,getSseeion的行为是

1.读取请求中Cookie的sessionId

2.在服务器这边根据sessionId查询对应的Session对象

3.如果查到了,就会直接返回这个session对象,如果没查到,返回null


如果参数为true,getSession的行为是:

1.读取请求中Cookie的sessionId

2.在服务器这边根据sessionId查询对应的Session对象

3.如果查到了,就会直接返回这个session对象

4.如果没查到,会创建一个Session对象,同时生成一个sessionId,以sessionIdkey,Session对象为value,把这个键值对存储到服务器里的一个hash表中,同时把sessionId以Set-Cookie的方式返回给浏览器


2.下面我们来模拟实现登录功能

需要两个页面

1.登录页(包含两个输入框,用户名和密码,还要有一个登录按钮)

点击登录,发起http请求

服务器处理这个请求的时候验证用户名密码

如果都是对的,就跳转到主页

2.主页

主页单纯的显示当前的用户名,是一个动态页面(欢迎xxx)

登录页就是一个HTML

还需要一个Servlet,实现登录时候的用户名密码校验

还需要一个Servlet来生成主页(主页的内容是动态的,)


开写


1.先写登录页的前端页面


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta namen="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录页面</title>
</head>
<body>
    <form action="login" method="post">
            <input type="text" name="username">
            <input type="password" name="password">
            <input type="submit" value="登录">
    </form>
</body>
</html>

e476178987144b43b4ebdef5577572de.png

form表单会组织这里的数据以键值对的形式提交给服务器

key就是input的name属性,

value就是input用户输入的内容

最终构造成post请求以键值对的形式进行组织

服务器通过getParameter来获取指定key的value

61990b3b107c45a59a95dbe1a005d236.png

2.编写login.HTML,处理登录请求

规定登录请求格式

POST/login

Content-Type:application/x-www-form-urlencoded


user=zhangsan&password=123

登录请求一般都用post

2.编写LoginServlet处理上述登录请求


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-10
 * Time: 14:53
 */
//这个Servlet用来实现登录时的校验
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.从请求拿到用户名密码
        //为了保证读出来的参数也支持中文,设置请求编码方式为utf8
        req.setCharacterEncoding("utf8");
        String  username=req.getParameter("username");
        String  password=req.getParameter("password");
        //2.验证用户名密码是否正确
        if(username==null||password==null||username.equals("")||password.equals("")){
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户名或密码不能为空");
            return;
        }
        //此处假设用户名只能是zhangsan 或者wangyibo,密码都是123
        //正常的登录逻辑,验证用户名密码都是从数据库读取的,此处为了方便,就不用了
        if(!username.equals("zhangsan")&&!username.equals("wangyibo")){
           //用户名有问题
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户名或密码有误");
            return;
            }
        if (!password.equals("123")){
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户名或密码有误");
            return;
        }
        //3.用户名和密码验证成功,创建会话
        //当前用户处于未登录状态,此时请求的cookie没有sessionId
        //此时的getSession无法从服务器的哈希表找到该session对象
        //由于此处把参数设置为true,所以允许getSession创建Session对象和sessionId
        //然后会自动把sessionId和session对象存储到哈希表中,
        //同时返回这个session对象,并且在接下来的响应中把这个sessionId返回给客户端浏览器
        HttpSession session=req.getSession(true);
        //让session存储自定义数据,存储用户信息
        session.setAttribute("username",username);
        //4.登陆成功之后,自动跳转到主页
        resp.sendRedirect("index");
    }
}


3.编写主页的代码


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;
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: WHY
 * Date: 2023-06-10
 * Time: 14:55
 */
//这个类用来实现动态生成主页面
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //此处禁止创建会话,如果没找到,认为用户是未登录的状态
        //如果找到了,才认为是登录状态
        HttpSession session=req.getSession(false);
        if(session==null){
            //当前未登录
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户未登录");
            return;
        }
        String  username=(String)session.getAttribute("username");
        //虽然有会话对象,但是没有属性,也认为是登录状态异常
        if(username==null){
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前用户未登录");
            return;
        }
        //如果都没问题,生成动态页面
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("欢迎你!"+username);
    }
}


我们的代码就写完了,来看一下结果

抓包来看看代码执行流程

这里是没有cookie的,点击登录,触发一个登录请求

第一个请求的响应有set-cookie

这里的

这个sessonid来自创建的sesssion会话

第二个请求

这里就有cookie了


最后得到结果


总结:实现登录的逻辑

1.读取用户名和密码

2.验证用户名密码

3.创建会话,保存必要信息

4.重定向到主页


上述的sessionId不会一直存在下去,当服务器重新启动的时候.原来hash表中的内容就没了

这时再次访问可能sessionId无法查询到,那么就是未登录状态

因为session默认保存在内存中

不过如果是Smart Tomcat,为了方便我们调试,可能会把会话持久化,这个要看smart Tomcat的版本

如果是手动部署到Tomcat,那会话还是默认保存在内存,重启会丢失

这里说一个小问题,为什么smart Tomcat不用打包就可以执行

解答:

smart tomcat会自动配置。通过target目录 和webapp目录访问

3.cookie和session的区别

1.Cookie 是客户端的机制. Session 是服务器端的机制.

2.Cookie 和 Session 经常会在一起配合使用. 但是不是必须配合.

3.完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是token / sessionId

4.Session 中的 token / sessionId 也不需要非得通过 Cookie / Set-Cookie 传递

5.session主要是来存用户的相关数据,cookie存什么都可以


这就是今天的全部内容了,我们下期再见了~~~

相关文章
|
19天前
|
存储 安全 搜索推荐
理解Session和Cookie:Java Web开发中的用户状态管理
理解Session和Cookie:Java Web开发中的用户状态管理
40 4
|
22天前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
1月前
|
缓存 Java Spring
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
文章比较了在Servlet和Spring Boot中获取Cookie、Session和Header的方法,并提供了相应的代码实例,展示了两种方式在实际应用中的异同。
164 3
servlet和SpringBoot两种方式分别获取Cookie和Session方式比较(带源码) —— 图文并茂 两种方式获取Header
|
1月前
|
存储 安全 数据安全/隐私保护
Cookie 和 Session 的区别及使用 Session 进行身份验证的方法
【10月更文挑战第12天】总之,Cookie 和 Session 各有特点,在不同的场景中发挥着不同的作用。使用 Session 进行身份验证是常见的做法,通过合理的设计和管理,可以确保用户身份的安全和可靠验证。
21 1
|
2月前
|
存储 缓存 数据处理
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
本文介绍了PHP会话控制及Web常用的预定义变量,包括`$_REQUEST`、`$_SERVER`、`$_COOKIE`和`$_SESSION`的用法和示例。涵盖了cookie的创建、使用、删除以及session的工作原理和使用,并通过图书上传的例子演示了session在实际应用中的使用。
php学习笔记-php会话控制,cookie,session的使用,cookie自动登录和session 图书上传信息添加和修改例子-day07
|
2月前
|
存储 前端开发 Java
JavaWeb基础7——会话技术Cookie&Session
会话技术、Cookie的发送和获取、存活时间、Session钝化与活化、销毁、用户登录注册“记住我”和“验证码”案例
JavaWeb基础7——会话技术Cookie&Session
|
2月前
|
存储 安全 NoSQL
Cookie、Session、Token 解析
Cookie、Session、Token 解析
62 0
|
3月前
|
存储 JavaScript 前端开发
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
Cookie 反制策略详解:Cookie加解密原理、Cookie和Session机制、Cookie hook、acw_sc__v2、jsl Cookie调试、重定向Cookie
210 1
|
3月前
|
存储 安全 搜索推荐
【JavaWeb 秘籍】Cookie vs Session:揭秘 Web 会话管理的奥秘与实战指南!
【8月更文挑战第24天】本文以问答形式深入探讨了Web开发中关键的会话管理技术——Cookie与Session。首先解释了两者的基本概念及工作原理,随后对比分析了它们在存储位置、安全性及容量上的差异。接着,通过示例代码详细介绍了如何在JavaWeb环境中实现Cookie与Session的操作,包括创建与读取过程。最后,针对不同应用场景提供了选择使用Cookie或Session的指导建议,并提出了保障二者安全性的措施。阅读本文可帮助开发者更好地理解并应用这两种技术。
61 1
|
3月前
|
存储 安全 搜索推荐
深入探讨Session和Cookie的概念、用途以及如何在Java Web开发中有效地使用它们进行用户状态管理。
在Java Web开发中,Session和Cookie是管理用户状态的核心技术。Session存储于服务器端,通过唯一的Session ID识别用户,确保数据安全与隐私;Cookie则存储于客户端,用于记录用户偏好等信息。两者各有优势:Session适合存储敏感数据,但需合理管理避免资源浪费;Cookie便于持久化存储,但在安全性上需谨慎设置。开发者可通过Servlet API轻松操作二者,实现个性化用户体验与应用性能优化。
60 2