你真的了解 Cookie 和 Session 吗?

文章目录

  • Cookie 和 Session
  • 总结

Cookie 和 Session

cookie

HTTP cookie(web cookie、browser cookie)是服务器发送给用户 web 浏览器的一小段数据。浏览器可能会存储 cookie,并在以后的请求中将其发送回同一台服务器。通常,HTTP cookie 用于判断两个请求是否来自同一个浏览器 - 例如,保持用户登录。它为无状态 HTTP 协议记住有状态信息。

cookie 主要用于三个目的:

  • 会话管理:登录、购物车、游戏分数或其它服务器需要保存的数据。
  • 个性化:用户首选项、主体和其它设置。
  • 跟踪:记录和分析用户行为。

示例:当你登录一次哔哩哔哩软件时,使用完成之后关闭掉该网站,下次开启电脑再次访问该网站时,你的账号依然是已经登录的状态。这实际上就是使用 cookie 实现的,如下所示,点击浏览器地址栏左侧的锁标志,你就可以看到对于网站的各种 cookie 数据了。

在这里插入图片描述

用户在通过身份验证并且服务器成功设置了 cookie 之后,服务器会将该 cookie 作为 HTTP 响应的一部分发送给浏览器。浏览器收到响应后会自动解析 cookie 的值,并将其保存在浏览器的 cookie 存储中。这样,用户的身份信息就会以加密的形式是保存在浏览器的 cookie 文件中。

当用户在之后的请i去中访问同一网站时,浏览器会自动将响应的 cookie 信息加到请求中的 cookie 标头中,并发送给服务器。服务器可以通过这些 cookie 信息来识别用户并提供个性化的服务,例如保持用户的登录状态。

在这里插入图片描述

浏览器会自动管理 cookie 的生命周期和安全性。如果你删除该网站对应的 cookie 信息,那么下次再访问时,就需要重新进行账号登录了。

注意:要查看存储的 cookie(以及网页可以使用的其它存储),你可以开启开发人员哦工具中的存储检测器并从存储树中选择 cookie。

cookie 被盗取

如果你存储在浏览器中的 cookie 信息被未经授权的用户盗取,那么该用户就可以使用你的 cookie 信息以你的身份来访问你之前访问过的网站。(例如:QQ被盗,身份泄密等)这种情况都称为 cookie 被盗取。

恶意链接是一种常见的网络攻击方式,黑客可以通过欺骗用户点击恶意链接来窃取其Cookie。以下是一个示例:假设您收到一封看似来自银行的电子邮件,邮件内容称您的账户存在异常,需要您点击链接以确认身份。然而,该链接实际上是一个恶意链接,当您点击时,黑客将会收到您的 Cookie 信息。一旦黑客获取了您的 Cookie,他们可以使用它来伪装成您,访问您的账户,进行各种恶意活动,如盗取个人信息、进行非法转账等。

什么是 Session

  • Session 代表了服务器和客户端之间的一次会话过程。在 Web 应用程序中,当用户与服务器建立会话时,服务器会为该用户创建一个唯一的 Session 对象。该 Session 对象用于存储特定用户会话所需的属性和配置信息。
  • 在整个用户会话中,当用户在应用程序的不同 Web 页面之间跳转时,存储在 Session 对象中的变量和数据不会丢失,而是持续存在。这使得应用程序能够跟踪和管理用户的状态和数据,以提供个性化的服务和功能。
  • 当客户端关闭会话(例如关闭浏览器)或者 Session 超时失效时,会话结束,Session 对象中的数据也随之销毁。会话超时时间通常由应用程序的配置决定,以平衡用户体验和服务器资源的利用。
  • 通过使用 Session,应用程序可以在用户会话期间保持持久性数据,并确保用户的状态和信息不会再页面跳转或重新加载时丢失。这对于实现登录认证、购物车功能、个性化设置都非常有用。

Cookie 和 Session 之间有什么不同?

  • 存储位置:Cookie 保存在客户端(浏览器)中,而 Session 保存在服务器端。
  • 存储内容:Cookie 只能保存 ASCII 字符,而 Session 可以存储任意数据类。通常情况下,我们可以在 Session 中保存一些常用的变量信息,如用户ID 等。
  • 有效期:Cookie 可以设置长时间保持,比如经常使用的默认登录功能。Session 的有效时间相对较短,通常在客户端关闭或 Session 超时后会失效。
  • 隐私策略:由于 Cookie 存储在客户端,相对容易收到非法获取的风险。在早期,有些网站将个人信息存储在 Cookie 中,导致信息被盗取。而 Session 数据存储在服务器中,相对来说安全性更高。
  • 存储大小:单个 Cookie 的存储容量有限,一般不超过 4KB。而 Session 可以存储的数据量远远超过 Cookie 的限制,因为它存储在服务器的内存或数据库中。

为什么需要 cookie 和 session 配合使用,它们之间的关联。

为什么需要使用 Cookie,这就要从浏览器说起,我们知道浏览器是没有状态的(HTTP 协议无状态),这意味着浏览器无法记住用户信息,这时就需要使用一个机制来告诉服务器,本次操作用户是否登录以及是哪一个用户等。而仅仅使用 Cookie 来存储用户数据存在安全风险,一旦 Cookie 文件泄漏,用户的隐私数据也会泄漏。因此,为了增加安全性,那这套机制的实现就需要 Cookie 和 Session 的配合。

在这里插入图片描述

在用户首次请求服务器时,服务器会根据用户提交的相关信息生成一个对应的 Session,并将 Session 的唯一标识信息(SessionID)返回给浏览器,浏览器收到 SessionID 之后,会将其存储在 Cookie 中并记录此 SessionID 属于哪个域名。

当用户再次访问服务器时,浏览器会自动判断此域名是否存在 Cookie 信息,并在请求中自动发送 Cookie 信息给服务器。服务器会从 Cookie 中获取 SessionID,并根据 SessionID 查找对应的 Session 信息。如果没有找到 Session,说明用户没有登录或登录失效;如果找到了 Session,就标识用户已登录,服务器可以根据 Session 中的信息执行后续的操作。

无论使用哪一种方案,安全都是相对的。

安全是相对的,没有绝对的安全性。无论是使用账号密码直接发送到网络中,还是使用 SessionID 进行身份认证,都存在一定的风险。即使使用加密等安全措施,也无法完全消除所有的潜在威胁。

安全性评估通常会考虑破解成本与收益之间的关系。如果破解某个信息的成本非常高,远远大于攻击获取信息带来的收益,那么这个信息就是相对安全的。因此,在设计安全系统时,我们尽量提高攻击者获取有价值信息的成本,以增加安全性。

对于使用 Session 的方式,尽管 SessionID 可能会被盗取,但相比直接在每次请求中发送账号和密码信息,它降低了账号密码被泄漏的风险。

HTTP 响应中设置 Cookie 字段

当浏览器访问服务器时,若服务器给浏览器的 HTTP 响应中包含 Set-Cookie 字段,那么浏览器再次访问该服务器时就会携带上该 Cookie 字段。

如下所示,当浏览器访问服务器时,我们给响应的报头中添加上一个 Set-Cookie 字段,测试当浏览器第二次访问该服务器时会不会携带上该 Cookie 字段。

#define CRLF "\r\n"
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define HOME_PAGE "index.html"
#define ROOT_PATH "wwwroot"

string getPath(string http_request)
{
    size_t pos = http_request.find(CRLF);
    if (pos == string::npos)
        return "";
    string request_line = http_request.substr(0, pos);
    // GET /a/b/c http/1.1
    size_t first = request_line.find(SPACE);
    if (first == string::npos)
        return "";
    size_t second = request_line.rfind(SPACE);
    if (second == string::npos)
        return "";

    string path = request_line.substr(first + SPACE_LEN, second - (first + SPACE_LEN));
    if (path.size() == 1 && path[0] == '/')
        path += HOME_PAGE;

    return path;
}

string readFile(const string &recource)
{
    ifstream in(recource, std::ifstream::binary);

    if (!in.is_open())
        return "404";
    string content;
    string line;
    while (getline(in, line))
        content += line;
    in.close();

    return content;
}

void handlerHttpRequest(int sock)
{
    cout << "---------------------------------------------------" << endl;
    char buffer[10240];
    ssize_t s = read(sock, buffer, sizeof buffer);
    if (s > 0)
        cout << buffer;

    string path = getPath(buffer);
    std::string recource = ROOT_PATH;
    recource += path;

    string html = readFile(recource);
    size_t pos = recource.rfind(".");
    string suffix = recource.substr(pos);
  
    // 开始响应
    std::string response;
    response = "HTTP/1.0 200 OK\r\n";
    if (suffix == ".jpg")
        response += "Content-Type: image/jpeg\r\n";
    else
        response += "Content-Type: text/html\r\n";
    response += ("Content-Length: " + to_string(html.size()) + "\r\n");
    response += "Set-Cookie: This is my cookie content;\r\n";
    response += "\r\n";
    response += html;

    send(sock, response.c_str(), response.size(), 0);
}

class ServerTcp
{
public:
    ServerTcp(uint16_t port, const std::string &ip = "")
        : port_(port), ip_(ip), listenSock_(-1)
    {
        quit_ = false;
    }

    ~ServerTcp()
    {
        if (listenSock_ >= 0)
            close(listenSock_);
    }

public:
    void init()
    {
        // 1. 创建socket
        listenSock_ = socket(PF_INET, SOCK_STREAM, 0);
        if (listenSock_ < 0)
        {
            exit(1);
        }

        // 2. bind
        // 2.1 填充服务器信息
        struct sockaddr_in local; // 用户栈
        memset(&local, 0, sizeof local);
        local.sin_family = PF_INET;
        local.sin_port = htons(port_);
        ip_.empty() ? (local.sin_addr.s_addr = INADDR_ANY) : (inet_aton(ip_.c_str(), &local.sin_addr));
        // 2.2 本地socket信息,写入sock_对应的内核区域
        if (bind(listenSock_, (const struct sockaddr *)&local, sizeof local) < 0)
        {
            exit(2);
        }

        // 3. 监听socket,为何要监听呢?tcp是面向连接的!
        if (listen(listenSock_, 5) < 0)
        {
            exit(3);
        }
    }

    void loop()
    {
        signal(SIGCHLD, SIG_IGN);
        while (!quit_)
        {
            struct sockaddr_in peer;
            socklen_t len = sizeof(peer);
            // 4. 获取连接,accept的返回值是一个新的socket fd
            int serviceSock = accept(listenSock_, (struct sockaddr *)&peer, &len);
            if (quit_)
                break;
            if (serviceSock < 0)
            {
                cerr << "accept error..." << endl;
                // 获取连接失败,继续获取
                continue;
            }
            // 4.1 获取客户端基本信息
            uint16_t peerPort = ntohs(peer.sin_port);
            std::string peerIp = inet_ntoa(peer.sin_addr);
            
            pid_t id = fork();
            assert(id != -1);
            if (id == 0)
            {
                close(listenSock_); // 建议
                if (fork() > 0)
                    exit(0);
                handlerHttpRequest(serviceSock);
                exit(0);
            }
            close(serviceSock);
            wait();
        }
    }

    bool quitServer()
    {
        quit_ = true;
        return true;
    }

private:
    int listenSock_;
    uint16_t port_;
    std::string ip_;
    bool quit_; // 安全退出
};

运行服务器并使用浏览器访问,此时我们通过 Fiddler 可以看到服务器给浏览器的 HTTP 响应报头中共包含了 Set-Cookie 字段。

在这里插入图片描述

总结

Cookie 和 Session 是 Web 开发中常用的数据存储和传递技术。Cookie 将数据存储在客户端浏览器,通过 HTTP 请求自动发送给服务器;而 Session 将数据信息存储在服务器中,通过 Cookie 或 URL 重写将 SessionID 发送给客户端。它们存储位置、数据容量、安全性、传输方式、生命周期和应用场景等方面都具有明显差异。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/171674.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

山西电力市场日前价格预测【2023-11-22】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-11-22&#xff09;山西电力市场全天平均日前电价为13.55元/MWh。其中&#xff0c;最高日前电价为243.27元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出现…

系统之家U盘重装系统Win10方法步骤

用户发现自己电脑上的Win10系统出现问题了&#xff0c;想要通过重装系统来解决问题。但是&#xff0c;用户还不清楚具体重新安装Win10系统的步骤&#xff0c;接下来小编给大家详细介绍利用U盘完成Win10系统重装的方法&#xff0c;在这里用户需要下载系统之家装机大师软件&#…

Linux fork和vfork函数用法

fork和vfork是用于创建新进程的函数&#xff0c;在Linux的C语言编程中非常常见。 fork函数 fork函数是用于创建一个新的进程&#xff0c;新进程是调用进程的副本。新进程将包含调用进程的地址空间、文件描述符、栈和数据。在fork之后&#xff0c;父进程和子进程将并发执行。 …

AR眼镜方案—单目光波导AR智能眼镜

光波导技术是一项具有前沿意义的技术&#xff0c;它能够将光线反射180度&#xff0c;使得眼镜框架内置的MicroLED屏幕的图像通过多次反射与扩散后准确地传递到人眼中。采用MicroLED显示技术的AR智能眼镜不仅体积显著缩小&#xff0c;屏幕只有0.68英寸大小&#xff0c;并且还能够…

企业数字化转型所需的数据在哪里找?企业数据运营有什么用?

现阶段&#xff0c;越来越多企业考虑数字化转型。特别是中小型企业&#xff0c;他们察觉到&#xff1a;数字化转型的关键在于数据的运营。只有通过数据的有效管理和不断挖掘&#xff0c;企业才可以更好地了解市场需求&#xff0c;优化业务流程&#xff0c;提高决策效率&#xf…

SAP smartform和ALV如何使用图片 如何下载SE78上传的图片到本地

原文链接1&#xff1a;https://mp.weixin.qq.com/s/gb3LCoDLNhZGnpplG68cyA 原文链接2&#xff1a;https://mp.weixin.qq.com/s/iFFhGwFEK93QiddR1biXyA 1.如何在SMARTFORM中打印图片 在使用SmartForms进行打印单据开发时候&#xff0c;经常需要将公司的LOGO、公司印章、管理人…

CTF/AWD竞赛标准参考书+实战指南

随着网络安全问题日益凸显&#xff0c;国家对网络安全人才的需求持续增长&#xff0c;其中&#xff0c;网络安全竞赛在国家以及企业的人才培养和选拔中扮演着至关重要的角色。 在数字化时代&#xff0c;企业为了应对日益增长的攻击威胁&#xff0c;一般都在大量部署安全产品、…

ACREL DC energy meter Application in Indonesia

安科瑞 华楠 Abstract: This article introduces the application of Acrel DC meters in base station in Indonesia.The device is measuring current,voltage and energy together with hall current sensor. 1.Project Overview This company is located in Indonesia a…

leetcode:415. 字符串相加(模拟竖式计算)

一、题目 链接&#xff1a; 415. 字符串相加 - 力扣&#xff08;LeetCode&#xff09; 函数原型&#xff1a;char* addStrings(char* num1, char* num2) 二、思路&#xff1a; 本题本质是将两个字符型数字相加&#xff0c;字符型数字相加就一定需要进行字符与数字的相互转换 详…

媒体格式转换软件Permute 3 mac中文版软件特点

Permute mac是一款媒体格式转换软件&#xff0c;可以帮助用户快速地将各种音频、视频和图像文件转换成所需格式&#xff0c;并提供了一些常用工具以便于用户进行编辑和处理。 Permute mac软件特点 - 支持大量格式&#xff1a;支持几乎所有常见的音频、视频和图像格式&#xff…

Demo 题记

Demo 1 输入一个摄氏温度的值&#xff0c;将它转变为华氏温度&#xff0c;并将结果输出 #输入一个摄氏温度的值&#xff0c;将它转变为华氏温度&#xff0c;并将结果输出 c float(input("请输入摄氏温度&#xff1a;"))print("对应的华氏温度为%.2f"%(9…

redis---非关系型数据库

关系数据库与非关系型数据库 redis非关系型数据库&#xff0c;又名缓存型数据库。数据库类型&#xff1a;关系型数据库和非关系型数据库关系型数据库是一 个机构化的数据库,行和列。 列&#xff1a;声明对象。 行&#xff1a;记录对象属性。 表与表之间的的关联。 sql语句&…

俄罗斯方块摆烂

package 俄罗斯方块;import java.awt.BorderLayout; import java.awt.Color; import java.awt.GridLayout; import java.awt.event.KeyEvent; import java.awt.event.KeyListener;import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import ja…

ZYNQ_project:lcd_pic_400x400

在lcd液晶屏上显示400x400像素的图片&#xff0c; 像素信息通过电脑的串口调试助手&#xff0c;发送给fpga&#xff0c;存储在例化的双端口ram中&#xff0c; 在要显示图像区域&#xff0c;读取ram中的像素信息。 模块框图&#xff1a; 时序图&#xff1a; 代码&#xff1a;…

电脑开不了机怎么办?三招帮你成功解决!

电脑是我们日常工作和生活的重要工具&#xff0c;但有时候它们也会出现开机问题。当电脑无法启动时&#xff0c;可能会让人感到焦虑&#xff0c;电脑开不了机怎么办&#xff1f;不必担心&#xff0c;通常有多种方法可以解决这些问题。本文将介绍三种常见的方法&#xff0c;以帮…

你真的会写简历吗?软件测试简历修改包装...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、简历重要性以及…

《微信小程序开发从入门到实战》学习二十三

前言 之前是先看文章&#xff0c;再敲代码&#xff0c;出现预览效果&#xff0c;最后码字。 现在改变顺序&#xff0c;先直接照着敲代码&#xff0c;再看文章&#xff0c;最后码字。不知道能不能更加内化学习到该书作者教的内容。希望自己不是一味照抄书的代码和内容。 ​3.…

【GitHub】保姆级使用教程

一、如何流畅访问GitHub 1、网易uu加速器 输入网址&#xff0c;无脑下载网易加速器&#xff1b;https://uu.163.com/ 下载安装完毕后&#xff0c;创建账号进行登录 登录后&#xff0c;在右上角搜索框中搜索“学术资源”&#xff0c;并点击&#xff1b; 稍等一会儿就会跳…

微信小程序会议OA-登录获取手机号流程登录-小程序导入微信小程序SDK(从微信小程序和会议OA登录获取手机号到登录小程序导入微信小程序SDK)

目录 获取用户昵称头像和昵称 wx.getUserProfile bindgetuserinfo 登录过程 登录-小程序 wx.checkSession wx.login wx.request 后台 准备数据表 反向生成工具生成 准备封装前端传过来的数据 小程序服器配置 导入微信小程序SDK application.yml WxProperties …