通过Cookie和Session来实现网站中登录账号的功能

news/2024/5/18 16:39:42 标签: Cookie, Session, 实现用户登录

文章目录

CookieSession_1">一、CookieSession

cookie是http请求header中的一个属性,是浏览器持久化存储数据的一种机制,因为网页无法直接访问浏览器所在主机的文件系统,所以网页要通过向cookie中存储键值对(Cookie中的键值对是程序员自定义的)的方式来把数据存储到浏览器所在主机的硬盘中。
cookie中保存的是键值对,最终还是要把这个键值对发送回服务器,因为服务器要使用cookie中的键值对来完成一些业务逻辑。
比如客户端请求中的cookie包含个人id,服务器就会通过这个个人id在数据库中查询出来这个个人id所关联的信息。
然而每个人都有一个个人id和个人id所关联的信息。这些数据是存储在数据库中的,服务器代码执行过程中这些数据会先临时保存到某个内存结构(相当于一个哈希表)中,后续需要对这些信息进行修改时,就修改内存结构(哈希表)中的内容,然后再将修改后的信息写入数据库。
这里服务器所涉及到的内存结构(哈希表)叫“会话”(session)。

cookie是客户端存储数据的机制。
session是服务器存储数据的机制(不是持久化存储)。
Cookie键值对中存储的用户身份标识经常会理解成sessionId(会话Id)。
服务器会存储很多的session信息(会话信息)和sessionId(会话Id),每个用户都有一个session信息以及sessionId。服务器会通过类似于哈希表这样的数据结构来存储session信息和sessionId,sessionId就是key,session信息就是value,session信息里可以存储用户自身的各种信息(session信息里也是程序员自定义的键值对)。

CookieSession_12">二、基于CookieSession实现登录账号的功能

2.1步骤一

浏览器发起html请求,服务器返回html登录页面,用户输入用户名和密码点击提交之后,浏览器会发送登录请求。

用前端代码写登录页面,通过from表单来构造post请求,用户在方框中输入用户名和密码点击登录后,前端就会向服务器发起一个post请求,用户输入的用户名和密码就会成为post请求的url中query string里的两个键值对,这时这个post请求的body格式就会自动设置成Content-Type: application/x-www-form-urlencoded这样的格式,而不需要我们手动设置。from表单也可以构造get请求,而这里不用get请求是因为get请求会把用户的用户名和密码显示到浏览器地址栏里,所以用GET请求不太好。

从上面可以看出客户端发送的请求是post请求,body类型为Content-Type: application/x-www-form-urlencoded。这是前后端交互时要约定好的。

以下为登录页面的前端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登陆</title>
</head>
<body>
<!-- 使用 form 表单, 实现登陆效果 -->
<form action="login" method="post">
    <input type="text" name="username">
    <input type="text" name="password">
    <input type="submit" value="登陆">
</form>
</body>
</html>

2.2步骤二

服务器通过一个Servlet处理上述登录请求,即通过一个Servlet读取用户名和密码并且验证是否登录成功。如果登录成功就给当前用户创建一个session信息(会话信息)和sessionId(会话Id),然后Servlet把这个sessionId和session信息保存到服务器的哈希表中,并且Servlet把sessionId设置到重定向响应中传回给浏览器(即在重定向响应头中加上Set-Cookie字段),然后浏览器通过Cookie里面的键值对来保存sessionId的值(sessionId=……),然后sessionId的值就被保存到浏览器本地中了。
服务器的Servlet代码如下:

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if(!"lingliang".equals(username) || !"123".equals(password)) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("用户名或密码错误");
            return;
        }
        HttpSession session = req.getSession(true);
        session.setAttribute("username", username);
        session.setAttribute("loginTime", System.currentTimeMillis());
        resp.sendRedirect("index");
    }
}

HttpSession session = req.getSession(true);这行代码会根据请求的cookie键值对中的sessionId查询服务器的哈希表来找对应的session信息对象,如果请求的cookie键值对中没有sessionId(比如首次登录的时候会没有),或者在服务器哈希表中没有查到sessionId对应的session信息对象,就会创建出一个新的session信息对象出来(如果没有sessionId的话也会创建出与session信息对象相对应的sessionId)。

然后Servlet把这个sessionId和session信息对象保存到服务器的哈希表中,并且Servlet会把sessionId设置到重定向响应中传回给浏览器(即在重定向响应头中加上Set-Cookie字段),然后浏览器通过Cookie里面的键值对来保存sessionId的值(sessionId=……),然后sessionId的值就被保存到浏览器本地中了。

getSession方法的参数设置成true则表示在服务器哈希表中找不到session信息时这个方法会创建一个新的session信息,设置成false则表示在服务器哈希表中找不到session信息时或没有sessionId时这个方法不会创建一个新的session信息而是返回null。

2.3步骤三

重定向响应会让浏览器触发一个GET请求,服务器会针对这个GET请求返回响应,即服务器通过另一个Servlet把用户数据返回给前端。然后前端再将数据显示到页面上。比如:凌亮用户登录成功后,就会显示“欢迎你,凌亮”。这相当于实现了登录成功后的页面跳转。
服务器的另一个Servlet代码如下:

@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");
        long loginTime = (long) session.getAttribute("loginTime");
        resp.setContentType("text/html; charset=utf8");
        String respBody = "欢迎你" + username +"! 你的上次登录时间为:" + loginTime;
        resp.getWriter().write(respBody);
    }
}

HttpSession session = req.getSession(false);这行代码会根据GET请求cookie中的sessionId查询服务器中的哈希表,getSession方法的参数设置成false。前面登录时getSession方法的参数设置成true是因为我们希望当服务器哈希表中没有session信息时我们能创建出一个新的session信息,而这里是登录完了之后然后访问主页,这个时候我们是不希望创建出新的session信息的,我们需要用到的是已有的旧的session信息,这体现了一个session信息可以在多个Servlet之间共享。

前端发送登录的请求后后端查询服务器哈希表时用的sessionId和前端发送跳转页面的GET请求后后端查询服务器哈希表时用的sessionId是同一个sessionId(因为我们用的是同一个浏览器来访问登录页面和主页,所以这两次用的sessionId都来自cookie里的同一个键值对,即两次用的sessionId都一样),所以两次查询出来的是同一个session信息。

重定向响应会触发GET请求,这个GET请求的首行为GET http://127.0.0.1:8080/hello_servlet/index Http/1.1。

CookieSession_93">2.4总结通过CookieSession来实现登录功能

在浏览器中首次进行登录操作的时候,服务器会进行身份验证,验证通过后服务器会创建具有身份标识的会话信息(即session信息和sessionId)并将其保存到服务器哈希表中,然后通过响应将sessionId返回给客户端。客户端也会用Cookie中的键值对来保存身份标识sessionId(sessionId=……)。后续浏览器访问这个网站的其它页面(即非登录页面)时,请求中Cookie中的键值对都会带有sessionId(sessionId=……),这时服务器就不需要让用户重新登录也能识别出用户的身份信息了(即自动登录)。自动登录相当于用户进入网站时是已登录状态,这个已登录状态通常是有过期时间的,可以给Cookie设置过期时间,一定时间之后浏览器会自动把Cookie删除掉;也可以给Session信息设置过期时间,一定时间之后服务器会自动删除session信息(通常给Session信息设置过期时间更靠谱一些,因为服务器掌握在程序员手里)。

2.5运行截图

在这里插入图片描述

在这里插入图片描述


http://www.niftyadmin.cn/n/5165622.html

相关文章

第二次pta认证P测试C++

#include <iostream> using namespace std; int f(int n){if (n0){return 1;}if (n1){return 3;}return 4*f(n-1)-f(n-2); } int n; int main() {cin>>n;cout<<f(n);return 0; }第二题 试题编号&#xff1a;2022-13-0302 试题名称&#xff1a;长正整数相加 …

起重行业信息汇集

1.行业专家委员会&#xff0c;标准汇集 记得起重机行业的技术委员会编号&#xff1a;TC227. 另外一个是起重电机技术委员会&#xff1a;TC26/SC3 全国标准信息公共服务平台 - 国标&#xff0c;行业标准https://std.samr.gov.cn/gb 相关企业&#xff0c;专家&#xff0c;标准…

github官网打不开或访问慢的解决办法

对国内程序员而言&#xff0c;github官网经常面临打不开或访问慢的问题&#xff0c;今天教你一招非常简单且好用的小技巧&#xff0c;轻松访问github官网。 1、github官网打不开的原因 首选我们说下github官网打不开的原因到底是什么。细心的同学会发现&#xff0c;github偶尔…

Django知识点

目录 一、三板斧的使用 二、全局配置文件 三、静态文件的设置 四、request对象的方法 五、pycharm链接数据库 六、Django链接数据库 七、orm介绍 一、三板斧的使用 三个方法&#xff1a; HttpResponse renderredirect def index(request):print(request)return HttpR…

Android Studio导入,删除第三方库

Android项目经常用到无私的程序员们提供的第三方类库。本篇博客就是实现第三方库的导入和删除。 一、导入第三方库 1、将需要的库下载到本地&#xff1b; 2、新建Moudle (1)File --- New Moudle (2)选择Android Library --- Next (3)填写Moudle名 --- Finish。一个新的Mou…

logback 将日志保存CSV文件

背景 公司业务&#xff0c;要将数据要做本地备份记录&#xff0c;开始直接保存json格式&#xff0c;但是太占用存储&#xff0c;所以使用csv格式保存。 思路 1、使用csvWriter &#xff0c;数据来时&#xff0c;将数据写入本地 不足&#xff1a; 如果每次数据来临时&#xf…

AI系统ChatGPT程序源码+AI绘画系统源码+支持GPT4.0+Midjourney绘画+已支持OpenAI GPT全模型+国内AI全模型

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

普华永道重磅发布创新数字化工具——iBAS智能银行流水分析解决方案

上海&#xff0c;2023年11月9日——今日&#xff0c;在第六届中国国际进口博览会上&#xff0c;全球领先的专业服务机构普华永道隆重推出了创新数字化工具&#xff1a;iBAS智能银行流水分析解决方案。该产品由普华永道自主研发&#xff0c;将抽象的监管核查要求变成了自动化落地…