Cookie和Session的工作流程是什么样的?5min学懂:简易用户登录(前端+后端+数据库)
创始人
2024-02-10 17:54:53

目录

前言

一、Cookie

1.1、Cookie从哪里来?

1.2、Cookie到哪里去?

二、Session

2.1、什么是sessionId?

三、Cookie和Session的区别

四、Cookie和Session的具体工作流程

五、代码实现用户登录

5.1、核心方法

5.2、代码


前言

        想要了解Cookie和Session的工作流程,首先需要来了解一下什么是Cookie,什么是Session?之后我将会用一个用户登录(附加:前端+后端 代码)的栗子,让你通透整个工作流程;


一、Cookie

        有时候需要让网页存储一些简单数据,但由于网页禁止js访问电脑硬盘(原因:安全性),所以就提供了特殊的api给网页用,Cookie就是最经典的一个方案,是浏览器在本地存储数据(存储到硬盘上)的一种机制;

 Cookie如何组织信息的?键值对的形式!(如下图)

Cookie是用来存放什么数据的?

  • 上次访问网页的时间;
  • 当前网页的访问次数
  • 当前访问网页网页的身份标识(最典型的应用场景);

特点:

  •         Cookie是按照域名维度来组织的,不同域名下有不同的Cookie;
  •         和query string一样,是程序员自定义的;
  •         每一个Cookie都是一个键值对;
  •         Cookie有个过期时间,到时自动清除;

        注意:Cookie不是缓存,是持久化数据的手段(保存在硬盘上),缓存的数据是用来提高访问速度的;

1.1、Cookie从哪里来?

        Cookie存在于浏览器,来源于服务器;

        解释:在网页中我们所观察的Cookie都是浏览器访问了某一个服务器后,服务器返回一个响应报文,在响应header中包含 一个/多个 Set-Cookie这样的资源(程序员自己在服务器代码中写的),浏览器接收响应后,就见Set-Cookie这样的数据保存到浏览器本地;

如下图Fiddler所捕捉到的Set-Cookie:

1.2、Cookie到哪里去?

        来自服务器,存储到浏览器,最后返回到服务器;

        解释:当浏览器保存了cookie后,下次访问同一网站,就会把之前存在本地的Cookie作为身份标识在http请求的header给返回到服务器,服务器就知道,喔,又是你来了~就把上次加载好的数据作为响应返回给浏览器;


二、Session

        服务器每一时刻接收到的请求是很多的;服务器为了区分这些请求分别是哪一个用户的,就需要记录用户和该用户信息之间的对应关系,这时Session会话机制就起到关键的作用!

        Session会话的本质就是一个哈希表,用来存放一些键值对;例如用户登录一个网站,Session的key就是用户名,value就是该用户的信息;

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

2.1、什么是sessionId?

        sessionId是由服务器生成的一个“唯一性字符串”,也可以理解为一个身份表示,通过这个,服务器就可以识别对应的用户;从session机制的角度来看,这个唯一性字符串称为 “sessionId”,但在整个登录流程来看,也可以把这个唯一字符称为 “token” ; 

如下图:


三、Cookie和Session的区别

  • Cookie是客户端机制,Session是服务器机制;
  • Cookie和Session经常一起配合使用,但不是必须配合使用;
  • 可以全都用Cookie来保存数据在客户端,这些数据不一定是用户身份信息,也不一定是token/sessionId;
  • Session的token/sessionId不一定非要通过Cookie/Set-Cookie传递;

四、Cookie和Session的具体工作流程

如下图:


五、代码实现用户登录

5.1、核心方法

把握一点:HttpSession就类似于HashMap~

方法描述
HttpSession getSession()

当服务器获取会话:

1.若该方法的参数为true,则判断当前会话是否存在,若不存在就创建一个新的键值对保存到哈希表中,并生成sessionId返回到浏览器,若存在则返回对应的HttpSession;

2.若该方法的参数为false,则判断当前会话是否存在,若不存在就返回null,若存在就返回HttpSession;

Object getAttribute(String name)

类似于HashMap的get()方法:

返回session会话中 name(key) 所对应的value;

若没有指定名称的对象,就返回null;

void setAttribute(String name, Object value)

类似于HashMap的put方法:

该方法使用指定的名称绑定一个对象到该 session 会话(绑定一对key,value);

5.2、代码

1. loginServlet实现登录界面的服务器,登录次数通过数据库持久化保存;(如下代码)

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;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 javax.sql.DataSource;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html; charset=utf8");//从客户端请求中获取用户名和密码String username = req.getParameter("username");String password = req.getParameter("password");//判定账户密码是否正确//这里假设已经注册的账户为://username:zhangsan  password:123if (!"zhangsan".equals(username) || !"123".equals(password)) {resp.getWriter().write("很抱歉,登录失败,您的用户名或密码输入错误!");return;}//登录成功System.out.println("" + username + "成功登录");//从数据库中获取该用户的登录次数int loginCount = 0;try {loginCount = load(username);} catch (SQLException e) {e.printStackTrace();}//由于登录成功,所以登录次数加一,保存到数据库中try {save(username, String.valueOf(++loginCount));} catch (SQLException e) {e.printStackTrace();}//设置Session//getSession的参数true表示若查找不到HttpSession,就会新建立一个,并生成//一个sessionId插入哈希表,通过Set-Cookie返回给浏览器HttpSession session = req.getSession(true);//HttpSession对象自身相当于一个哈希表,可以根据需求设置里面的参数session.setAttribute("username", "zhangsan");session.setAttribute("loginCount", loginCount);//设置重定向到主界面indexresp.sendRedirect("index");}//修改数据库中的数据(登录次数)private void save(String username, String loginCount) throws SQLException {//创建数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/login?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1111");//不嫌麻烦,你就来攻击~//建立连接Connection connection = (Connection) dataSource.getConnection();//构造sqlString sql = "update message set loginCount = ? where name = ?";PreparedStatement statement = connection.prepareStatement(sql);statement.setString(1, loginCount);statement.setString(2, username);//执行sqlint ret = statement.executeUpdate();//打印日志System.out.println("ret = " + ret);//关闭数据库statement.close();connection.close();}//从数据库中获取登录次数private int load(String username) throws SQLException {//创建数据源DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/login?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("1111");//不嫌麻烦,你就来攻击~//建立连接Connection connection = (Connection) dataSource.getConnection();//构造sqlString sql = "select loginCount from message where name = ?";PreparedStatement statement = connection.prepareStatement(sql);statement.setString(1, username);//执行sqlResultSet resultSet = statement.executeQuery();int loginCount = 0;while(resultSet.next()) {//这里只对应一个结果loginCount = resultSet.getInt("loginCount");}//关闭数据库statement.close();connection.close();return loginCount;}
}

2. indexServlet实现登录后主页面的反馈;(如下图)

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("/index")
public class indexServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html; charset=utf8");//判断当前用户是否已经登录//getSession参数为false,表示若没有创建过HttpSession,则返回null;//若创建过,则返回该对象HttpSession session = req.getSession(false);if(session == null) {resp.getWriter().write("很抱歉,尚未登录");//重定向到indexresp.sendRedirect("login");return;}//已登录过,就从Session中访问数据//这里由于getAttribute返回的是Object类型,所以这里需要强转成StringString username = (String)session.getAttribute("username");int loginCount = (int)session.getAttribute("loginCount");resp.getWriter().write("欢迎回来:" + username + "~" + "
"+ "您今日已经登录了:" + loginCount + "次");} }

3. login.html 一个简易登录界面,用来发送post请求登录



登录界面

登录界面

输入后点击登录,若信息正确自动跳转

账户
密码

上一篇:代表金钱的词语

下一篇:17 软专

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...