当前位置:首页 » 《关注互联网》 » 正文

前端必备技能:全面解析 Cookie 在 Web 开发中的应用

0 人参与  2024年12月01日 10:01  分类 : 《关注互联网》  评论

点击全文阅读


在这篇文章中我们将深入探讨前端cookie、session、token和jwt等web开发中常见的身份认证和状态管理技术,它们在用户身份验证、数据存储授权和安全性方面发挥着重要作用,接下来开始逐一解释它们的含义、作用和各自的优势及其使用。

目录

初识cookie

cookie使用


初识cookie

cookie是什么:也叫web cookie或浏览器cookie,是服务器发送到用户浏览器并保存在本地的一小块数据,浏览器会存储cookie并在下次向同一服务器再发起请求时携带并发送到服务器上,通常它用于告知服务端两个请求是否来自同一浏览器—如保持用户的登录状态,cookie使基于无状态的http协议记录稳定的状态信息成为了可能。

cookie主要用于以下三个方面:

1)会话状态管理

如用户登录状态、购物车、游戏分数或其他需要记录的信息

2)个性化设置

如用户自定义设置、主题和其他设置

3)浏览器行为追踪

如跟踪分析用户的行为等

比如我们随便拿一个我们以往登录的网站,F12找到应用,然后打开Cookie可以看到如下信息:

以下是cookie中常用的属性解释:

1)name:第一个也就是cookie的名字

2)value:第二个也就是cookie的值

3)Domain:第三个也就是可以知道cookie站点的域名

4)Path:第四个也就是定义了web站点上可以访问该cookie的目录

5)Expires:第五个也就是表示cookie的过期时间,即有效值

6)Size:第六个表示cookie的大小

7)HttpOnly:一种安全性增强的措施,旨在防止客户端的js代码访问该cookie

8)secure:告诉浏览器当前cookie只能用https协议进行传输

9)samesite:用来控制浏览器如何在跨站请求中发送cookies,防止一些常见的安全问题如跨站请求伪造(CSRF)攻击

10)

当浏览器向服务器发送http请求时,服务器可以在响应中通过Set-Cookie头部设置一个或多个cookie,这些cookie会被存储在客户端浏览器中,通常包括以下几个基本信息:

1)名称:cookie的名字(例如 user_id)。
值:cookie的内容或数据(例如 123456)。
2)过期时间:cookie的有效期。可以通过 Expires 或 Max-Age 指定。如果没有设置过期时间,cookie默认会在浏览器会话结束时过期(即浏览器关闭时)。
3)路径:指定cookie适用的路径,只有该路径下的网页才能访问这个cookie。
4)域:指定cookie适用的域,通常是发送cookie的服务器域名。
5)安全标志:如果设置了secure,则cookie只能通过https协议传输。
6)HttpOnly 标志:如果设置了HttpOnly,该cookie只能通过http协议访问,js无法访问增加了防止 XSS 攻击的安全性。

cookie的作用:主要用于在浏览器与服务器之间维持会话状态,通常在用户登录后浏览器会存储cookie以标识用户的身份,每次用户访问网站时浏览器会自动将对应的cookie随http请求一起发送给服务器,服务器校验通过之后就会通过set-cookie的方式发送给浏览器,下次浏览器发起请求的时服务器通过校验cookie即可,如下图所示:

cookie的原理:通过在客户端(即浏览器)存储小型数据,从而实现服务器与客户端之间的状态保持和信息传递,如下图所示:

cookie的主要工作流程如下:

1)首次访问网站:浏览器向服务器发送请求服务器根据需要通过set-cookie响应头发送cookie

2)浏览器存储cookie:将其与网站的域名、路径等关联,保证cookie在后续请求中可用
3)后续请求:浏览器自动将与该网站域名匹配的cookie添加到请求的cookie头部,服务器读取cookie进行身份验证或数据维护
4)服务器响应:服务器可以通过设置新的cookie或更新现有的cookie来管理会话状态
5)cookie过期/删除:浏览器会根据cookie的过期时间或set-cookie的指示删除无效cookie

cookie的生成:cookie主要有以下两种方式生成:

1)服务端生成:在http responee header中set-cookie

2)客户端生成:通过document.cookie设置

cookie的误用:cookie的设计初衷是用于维持http状态的,不用于存储数据,原因如下:

1)大小限制:每个cookie项只能存储4k数据

2)性能浪费:cookie附带在http请求上,请求量过大,会导致每个http请求变得非常庞大

cookie使用

document操作:对于前端来讲我们可以通过document进行对cookie的操作,在浏览器的控制台当中输入document.cookie就可以获取当前网页的部分cookie信息,获取的字段可以用split函数将其拆分开来,如下所示:

它的序列化方式是:k1=v1; k2=v2; k3=v3 的方式,在浏览器中实际存储的不只当前网页cookie,浏览器当中设置的cookie也是使用的document.cookie,在浏览器当中设置cookie的方式如下,在浏览器的cookie存储当中可以看到我们设置的cookie已经成功被存储了,方式是会话存储:

如果想执行cookie的删除操作的话,可以借助max-age属性,其特点就是max-age=-1意味着直接删除cookie,max-age=60意味着60秒之后删除cookie,可以通过如下的命令执行:

然后我们可以通过js代码来设置一个自带有效期的cookie,cookie的expires属性来为其指定一个终止日期,expires属性应该是一个GMT格式的日期字符串,表示cookie的过期时间,当浏览器的时间达到这个过期时间时,cookie就会被自动删除,如下:

function setCookieWithExpiration(name, value, daysToExpire) {      var date = new Date();      date.setTime(date.getTime() + (daysToExpire * 24 * 60 * 60 * 1000)); // 设置过期时间为指定的天数之后      var expires = "; expires=" + date.toUTCString(); // 转换为GMT格式的字符串      document.cookie = name + "=" + (value || "") + expires + "; path=/"; // 设置cookie  }    // 使用示例  setCookieWithExpiration('myCookie', 'myValue', 7); // 名为myCookie的cookie,值为myValue,7天后过期

当然读取和删除的功能操作也是和上面一样的,借助document进行操作,代码如下:

// 读取cookiefunction getCookie(name) {      const value = `; ${document.cookie}`;      const parts = value.split(`; ${name}=`);      if (parts.length === 2) return parts.pop().split(';').shift();  }  getCookie(username)  // jackgetCookie(password)  // 123// 删除Cookie,直接把expires属性指定一个过去的时间,cookie就会被自动删除// 删除单个function deleteCookie(name) {         document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';  }  deleteCookie('password');// 删除所有function deleteAllCookies() {      var cookies = document.cookie.split(";");        for (var i = 0; i < cookies.length; i++) {          var cookie = cookies[i];          var eqPos = cookie.indexOf("=");          var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie;          document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";      }  }    // 使用示例  deleteAllCookies();

判断是否存在cookie也可以采用如下的方式进行:

function hasCookie(name) {      var nameEQ = name + "=";      var ca = document.cookie.split(';');      for(var i=0;i < ca.length;i++) {          var c = ca[i];          while (c.charAt(0)==' ') c = c.substring(1,c.length);          if (c.indexOf(nameEQ) == 0) return true;      }      return false;  } hasCookie('password');  // 不存在返回falsehasCookie('username'); // 存在返回true

js-cookie操作:前端我们也可以借助第三方库进行操作cookie,终端执行如下命令进行安装:

npm install js-cookie

安装完成之后我们就可以在文件中进行使用了,如下所示:

import Cookies from "js-cookie";// 写入cookieCookies.set('name', 'value')// 读取Cookies.get('name') // => 'value'Cookies.get('nothing') // => undefined// 读取所有可见的cookieCookies.get()// 删除某项cookie值Cookies.remove('name')

当然我们也可以通过该第三方库进行设置cookie及其过期时间以及删除功能:

//1、存cookie  set方法支持的属性有 :  expires->过期时间    path->设置为指定页面创建cookie   domain-》设置对指定域名及指定域名的子域名可见  secure->值有false和true ,表示设置是否只支持https,默认是falseCookies.set('key', 'value');  //创建简单的cookieCookies.set('key', 'value', { expires: 27 });//创建有效期为27天的cookieCookies.set('key', 'value', { expires: 17, path: ''  }); //可以通过配置path,为当前页创建有效期7天的cookielet seconds = 10;let expires = new Date(new Date() * 1 + seconds * 1000);Cookies.set('username', 'tanggaowei', { expires: expires }); // 10 秒后失效 //2、取cookieCookies.get('key'); // 获取指定key 对应的valueCookies.get(); //获取所有valueCookies.getJSON('name'); // 如果存的是对象如{ foo: 'bar' },可以使用该命令解析Cookies.getJSON(); // => { name: { foo: 'bar' } }//3、删除cookieCookies.remove('key');//删除普通的cookieCookies.remove('name', { path: '' }); // 删除存了指定页面path的cookie

发送cookie请求:在前端想要发送包含cookie的请求时,需要确保以下几个方面的配置和操作:

1)确保服务器设置了正确的 Set-Cookie 头部:首先服务器需要在响应中设置正确的Set-Cookie头部,并且根据需要配置SameSite、Secure、HttpOnly等属性。例如:

Set-Cookie: sessionId=abc123; SameSite=Lax; Secure; HttpOnly

SameSite:控制 cookie 在跨站请求中的行为,设置为 Strict、Lax 或 None。
Secure:表明该 cookie 只能通过 HTTPS 传输。
HttpOnly:表示该 cookie 只能由服务器读取,客户端 JavaScript 无法访问。

2)前端发送请求时要包括cookies:前端在发送请求时需要配置withCredentials,尤其是在发送跨域请求时,才能确保浏览器携带cookies,只有需要处理跨域请求时才需要设置withCredentials对于同源请求,浏览器默认会发送cookies:

axios.defaults.withCredentials = true; // 全局设置  // 或者在单个请求中设置  axios.get('https://api.example.com/data', {    withCredentials: true  })  .then(response => {    // 处理响应  })  .catch(error => {    // 处理错误  });

3)确保跨域时服务器允许携带cookies:当你发送跨域请求时,服务器需要设置Access-Control-Allow-Credentials头为 true,否则浏览器不会发送cookies,同时服务器需要允许特定的来源(Access-Control-Allow-Origin),但这个值不能设置为 *,而是要设置为实际允许的域名:

Access-Control-Allow-Credentials: trueAccess-Control-Allow-Origin: https://yourfrontenddomain.com
axios.get('https://api.example.com/data', {    headers: {      Cookie: 'your=cookie; another=cookie' // 这里的值应该是你希望发送的Cookie字符串    }  })  .then(response => {    // 处理响应  })  .catch(error => {    // 处理错误  });

总之:cookie扮演着重要的角色用于在客户端存储和传递小型数据,常见于会话管理、用户认证以及个性化设置等场景,通过前端js操作cookie我们能够灵活地读取、创建、更新和删除 cookie,从而提升用户体验:

1)读取cookie:可以通过 document.cookie 获取所有的 cookie 数据,注意它以键值对的形式存在,且不支持直接读取单个 cookie,因此需要进行字符串解析。
2)设置cookie:通过 document.cookie 设置 Cookie 时,需要指定键值对、过期时间、路径、域名等属性。合理的配置 SameSite、Secure 和 HttpOnly 等属性能提高cookie的安全性。
3)删除cookie:通过设置 expires 为过去的时间,或使用 max-age 为负数,可以清除 Cookie 数据。
4)跨域与安全性:在跨域请求中,前端需要确保使用 credentials: 'include'(或在 XMLHttpRequest 中设置 withCredentials)来携带 cookies,服务器需要配置 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 来支持跨域的 Cookie 传递。同时,设置 Secure 和 SameSite 可以防止 CSRF 攻击和其他安全漏洞。

        通过深入理解cookie的存储和传递机制,我们能够确保前端应用的稳定性和安全性,同时提升用户体验,特别是在处理用户认证、会话管理等场景时,前端开发者应当时刻关注cookie的存取权限、过期机制以及跨域时的安全性设置,以应对日益复杂的 Web 环境和潜在的安全威胁。


点击全文阅读


本文链接:http://zhangshiyu.com/post/194812.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1