cookie是什么

cookie的英文意思是饼干。在计算机术语中指服务端存放在客户端的一段数据。这段数据在客户端每次进行http请求时会自动加在http请求报文中的header上;服务端在响应时,可以对cookie进行设置,并将cookie加入到http响应报文header中。MDN中对cookie的解释为:cookie 是一个请求首部,其中含有先前由服务器通过 Set-Cookie 首部投放并存储到客户端的 HTTP cookies。
cookie一般存放在对应的域名下,各个浏览器对中一个域名下存放的cookie的个数与大小规定不一样。下表是不同浏览器对cookie存放的规定:

浏览器 chrome Safari Firefox ie
个数 53 无限制 50 50
大小 4097字节 4097字节 4097字节 4095字节
超额处理 剔除最老的cookie 剔除最老的cookie 随机消除除最新的其他cookie 剔除最老的cookie

所有浏览器都支持cookie功能,我们可以直接在浏览器中移除cookie与禁用cookie存储。chrome中的设置为:设置-高级-隐私设置和安全性-内容设置-cookie。
如果我们在创建cookie时没有设置过期时间,即没有设置expires或者max-age值,则该cookie只存在与会话中,此时,cookie存储在浏览器的内存中,关闭浏览器时cookie自动消失。如果设置了过期时间,则cookie存储在用户的硬盘上。
在windows OS下chrome存放cookie的路径是C:Documents and SettingsAdministratorLocal SettingsApplication DataGoogleChromeUser Data,firefox的存放路径是:C:Documents and SettingsAdministratorLocal SettingsApplication DataMozillaFirefoxProfilesznyzv8y6.defaultOfflineCache
在mac下chrome的存储路径为:~/library/application support/google/chrome;
Safari的存储路径为:~/library/cookies;

cookie的工作原理

我们知道http协议是一种无状态的协议,在web应用程序中,通过http协议进行数据交互,交互完毕后,客户端与服务端的连接就断开。再次交互需要建立新的连接。这种连接无法记录用户的状态,cookie可以弥补HTTP协议无状态的不足。服务器给客户端们颁发一个通行证,无论谁访问都必须携带自己通行证,这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。

上图展示了cookie的工作原理:
(1)第一次用户登录的时候,输入用户名和密码信息,服务端接收后进行用户认证。
(2)服务端通过验证后,生成一个token以cookie的形式放在http的response header中一起返回给客户端。
(3)浏览器根据是否设置cookie的过期时间判断该cookie是会话cookie还是永久cookie,并将cookie存储在不同的位置。
(4)下次进行http请求时,请求头中会自动携带存储的cookie。
(5)服务端根据请求头中的cookie里面的token确认该用户的身份信息。

常见问题

前端主动向后端跨域发送cookie

在解释这个问题之前先了解一下什么是跨域。两个域之间是不是存在跨域问题,主要是根据协议、域名、端口号这三个点进行判断,只要有一个不一样就是跨域。例如:
(1)协议不同:http://www.baidu.comhttps://www.baidu.com
(2)域名不同:http://www.baidu.comhttp://www.google.com
(3)端口号不同: http://www.baidu.com:8080 与http://www.baidu.com:8000
浏览器默认情况下无法主动跨域向后端发送cookie,需要在前端请求时加入配置项{withCredentials:true}。
jquery:
$.ajax({url:'myurl',method:'GET', xhrFields:{withCredentials:true},success:function(){}});
angular:
$http.get(url, {withCredentials: true})
axios:
axios.defaults.withCredentials = true

前端配置好后还需要在后端进行相关配置:
在response header里面添加配置项

"Access-Control-Allow-Credentials“, “true”
"Access-Control-Allow-Origin", ”yourdomain“

也有一些中间件帮我们解决跨域问题。例如express中的express-cors,或者koa中的koa-cors

方法属性

前端cookie

设置:

document.cookie = 'company=eoitek;max-age=10000;domain=eoitek.com;path=/;secure'

其中max-age是cookie的过期时间,是一个相对时间,值的单位是秒,是相对于cookie创建后多少秒才过期。与max-age相似的配置属性是expires,值为日期对象的toUTCString()格式,即Thu, 21 Sep 2018 06:10:38 GMT,是指cookie过期的绝对时间。如果max-age和expires都存在,则max-age的优先级更高。domain是我们设置cookie存放的域,如果没有设置则为当前主机的域。path是指cookie存储的目录,默认为当前文件的存储目录。secure,加入此配置项,则指定该cookie只能通过https协议进行传输。
读取:

document.cookie

读取所有该域能获取到的cookie;格式为‘<key1>=<value1>;<key2>=<value2>;’

后端cookie

设置(以node为例):

var http = require('http');
http.createServer(
function(req, res) {
res.setHeader('status', '200 OK');
res.setHeader('Set-Cookie', 'name=binbinfang;path=/;
max-age=1000;domain=eoitek.com');
res.setHeader('Access-Control-Allow-Origin', 'eoitek.com');
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.write('Hello World');
res.end();
}).listen(8888); console.log('running localhost:8888');

后端cookie比前端cookie多两个配置项:
httpOnly:设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由 Document.cookie 属性、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击(XSS);
SameSite=Strict
SameSite=Lax
允许服务器设定一则 cookie 不随着跨域请求一起发送,这样可以在一定程度上防范跨站请求伪造攻击(CSRF)。

注意事项

(1)保存中文cookie
如果需要保存中文cookie,则需要对中文进行UTF-8编解码,即通过encodeUriComponent()和decodeUriComponent()方。
(2)保存图片和安全证书
cookie中也可以保存二进制图片和安全证书,需要对文件进行base64编码才能保存。不过建议最好不要将这类文件保存在cookie中。
(3)cookie的更新
只要将key;path;domain一致,则可以通过改变key对应的value来更新cookie的值。
(4)cookie的删除
cookie只能更新不能删除,如果想要删除一个cookie,则通过更新设置该cookie的max-age=0即可。
(5)cookie的安全性
设置cookie时添加secure。

cookie由于其设置和取值都是通过字符串的形式进行的。因此,在原生cookie的操作比较麻烦,可通过一些js库来方便我们的操作,包括cookies.js和js-cookie

cookie的跨域获取与单点登录问题

默认情况下,cookie是不能跨域访问的,如在www.google.com域无法操作和获取www.baidu.com里面的cookie,因为他们的一级域不同。但是在二级域里面可以共享和修改cookie的。即www.baidu.com和baike.baidu.com之间是可以共享cookie的。据此,可以实现单点登录。
单点登录:多个不同系统整合到统一加载个平台,用户在任何一个系统登录后,可以访问这个统一加载上的所有系统。登录之后,用户的权限和信息不再受某个系统的限制,即使某个系统出现故障(包括统一加载平台),其他系统还是能正常使用的。这就需要用户权限等信息保存到客户端,不受服务器的限制。
例如,我们有两个站点,都需要用户身份认证,要实现单点登录的话,可以将他们的一级域名设置为相同的,如主站点设置为eoitek.test,子站点设置为sharplook.eoitek.test。在创建cookie的时候,通过设置domain=.eoitek.test;path=/;即可实现两个域名之间的cookie共享,如果将认证信息的token放在cookie中则可以实现单点登录了。

//eoitek.test站点

import cookies from 'cookiesjs';
export default {
name: 'agent',
mounted() {
cookies({'fullname': null, 'company': null});
if (!cookies('fullname')) {
cookies({fullname: 'binbin', company: 'eoitek'},
{expires: 100 * 24 * 3600,
domain: '.eoitek.test', path: '/'});
}
}
}

可以看出在两个站点中都能访问到我们设置的两个cookie,这样实现了跨域访问cookie和单点登录。

前端分享之cookie的使用及单点登录的更多相关文章

  1. .NET Core2.0+MVC 用Redis/Memory+cookie实现的sso单点登录

    之前发布过使用session+cookie实现的单点登录,博主个人用的很不舒服,为什么呢,博主自己测试的时候,通过修改host的方法,在本机发布了三个站点,但是,经过测试,发现,三个站点使用的sess ...

  2. Asp.Net Core基于Cookie实现同域单点登录(SSO)

    在同一个域名下有很多子系统 如:a.giant.com  b.giant.com   c.giant.com等 但是这些系统都是giant.com这个子域. 这样的情况就可以在不引用其它框架的情况下, ...

  3. NET Core 2.0使用Cookie认证实现SSO单点登录

    NET Core 2.0使用Cookie认证实现SSO单点登录 之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sa ...

  4. 基于Cookie跨域的单点登录问题

    由于项目中,需要用的单点登录,主要的思路是:系统1:用户名密码-->写入Cookie-->其他系统读取Cookie. 1.在同一个服务器下的Cookie共享 @Component(&quo ...

  5. .NET Core2.0+MVC 用session,cookie实现的sso单点登录

    博主刚接触.NET Core2.0,想做一个单点登录的demo,所以参考了一些资料,这里给上链接: 1.http://www.cnblogs.com/baibaomen/p/sso-sequence- ...

  6. CORS跨域、Cookie传递SessionID实现单点登录后的权限认证的移动端兼容性测试报告

    简述 本文仅记录如标题所述场景的测试所得,由于场景有些特殊,且并不需兼容所有浏览器,所以本文的内容对读者也许并无作用,仅为记录. 场景.与实现 需在移动端单点登录 需在移动端跨域访问我们的服务 基于历 ...

  7. 使用Cookie实现跨域单点登录的原理

    对于构建分布式系统来说业务功能的物理部署会随着新业务模块的增加而增加或改变物理部署的位置.而每个用户都有统一的帐号作为我们登录系统时的一个认证.当新业务或子系统部署在不同的物理机上,我们去访问不同的业 ...

  8. ASP.NET Core 2.0使用Cookie认证实现SSO单点登录

    之前写了一个使用ASP.NET MVC实现SSO登录的Demo,https://github.com/bidianqing/SSO.Sample,这个Demo是基于.NET Framework,.NE ...

  9. redis+cookie+json+filter实现单点登录

    目录: 1.项目集成redis客户端jedis 引入Jedis pom 2.redis连接池构建及调试 1)JedisPoolConfig源码解析 2)JedisPool源码解析 3)JedisPoo ...

随机推荐

  1. Automatic Setup of a Humanoid

    The humanoid animation option in Unity 4 makes it possible to retarget the same animations to differ ...

  2. day46-守护线程

    #1.守护线程要注意的坑:下面代码只能打印出子线程开始,无法打印出子线程执行完毕,因为主线程在t.start()以后就结束了, #而子线程要睡眠1秒,所以子线程守护线程随着主线程的结束而结束了. fr ...

  3. mysql按表字段内容长度排序

    今天遇到个需求如下: 查询一下新的业务是否正常入库,遇到的问题是新旧业务用的是同一个字段标识,唯一不同的是字段里内容的长度不同 查询方式如下,mysql按表字段内容长度排序 SELECT * FROM ...

  4. VB6实现Excel多工作簿数据合并

    以前的同事,工作需要,让我帮忙完成多个工作簿的汇总. 我就用最熟悉的VB6写了一个Form应用程序,这是因为我不知道她目前的系统和Office情况,如果太高大上了,她不会部署安装.索性就简单粗暴地来个 ...

  5. Hadoop_在linux中安装hadopp出现的问题

    问题 sudo: no valid sudoers sources found, quitting 网络解决方法 链接:sudo: no valid sudoers sources found, qu ...

  6. ML modeling process

    一.数据读取Load Data 二.数据分析EDA 三.数据预处理 四.特征工程Feature engineering 五.modeling & Tuning 六.Result 七.other ...

  7. [Machine Learning] Andrew Ng on Coursera (Week 1)

    Week 1 的内容主要有: 机器学习的定义 监督式学习和无监督式学习 线性回归和成本函数 梯度下降算法 线性代数回归 主要是了解一下机器学习的基本概念,重点是学习线性回归模型,以及对应的成本函数和梯 ...

  8. 【转】mac os x配置adb命令的方法,苹果电脑设置adb命令的方法

    http://www.myexception.cn/operating-system/1636963.html 步骤如下: 1. 启动终端Terminal (如果当前用户文件夹下已有.bash_pro ...

  9. 从源码看commit和commitAllowingStateLoss方法区别

    Fragment介绍 在很久以前,也就是我刚开始写Android时(大约在2012年的冬天--),那时候如果要实现像下面微信一样的Tab切换页面,需要继承TabActivity,然后使用TabHost ...

  10. NIO详解

    目录 NIO 前言 IO与NIO的区别 Buffer(缓冲区) Channel(通道) Charset(字符集) NIO遍历文件 NIO 前言 NIO即New IO,这个库是在JDK1.4中才引入的. ...