cookie和session

Cookie

什么是 Cookie

在服务端返回数据时,通过设置 Set-Cookie 头到浏览器中,并保存到浏览器的内容,这个内容就是 Cookie。

浏览器保存 Cookie 之后,在下次同域的请求当中,就会带上这个 Cookie,实现用户访问网站的会话当中的数据是一致的。可以设置多个 Cookie,以键值对的方式保存在浏览器。

通过 Set-Cookie设置

下次请求会自动带上

键值对,可以设置多个

Cookie 属性

max-ageexpires 设置过期时间

Secure 只在 https 的时候发送

HttpOnly 无法通过 document.cookie 访问,基于安全性考虑,如 csrf 攻击,通过在用户网页注入脚本或 url,引导用户给攻击者的服务器发送用户使用网站的 Cookie,攻击者拿到用户登录状态,并利用 Cookie 访问网站保存的用户数据。所以禁止重要数据通过 JS 进行访问,是保证用户数据安全非常重要的一步

Cookie 的使用

通过 JS 访问 Cookie 的内容

命令行 node server.js 启动服务器,8888端口打开网页。

服务器通过 Set-Cookie 设置 Cookie 的值。

控制台->application->Cookies,可以看到 Cookie 的信息。

network查看,localhost 文件请求头中有 Cookie,响应头中也有 Cookie,因为每次服务器都会下发。

通过 JS,document.cookie 可以拿到 Cookie 的值 123。

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  if (request.url === '/') {
    const html = fs.readFileSync('test.html', 'utf8')
    response.writeHead(200, {
      'Content-Type': 'text/html',
      'Set-Cookie': '123' // 通过 Set-Cookie 设置 cookie 值
    })
    response.end(html)
  }

}).listen(8888)

console.log('server listening on 8888')
复制代码
// test.html
<script>
  console.log(document.cookie)
</script>
复制代码
返回多个 Cookie

在 network 中,localhost 文件的响应头中有两个 Set-Cookie头,说明服务器下发了多个 Cookie,并且在 Response Headers 中是可以重复的。

在 application 的 Cookies 中 可以看到两条 cookie 数据。

'Set-Cookie': ['123','abc=456'] // nodejs中通过数组的形式设置多个 Cookie
复制代码
Cookie 时效

Cookie 有时效性。

如果没有设置过期时间,当浏览器关闭之后,Cookie 消失。第一次访问时,查看 network发现并没有 Cookie,刷新后会带上 Cookie。application 中是有数据的,这个是浏览器下发的。

设置 Cookie 过期时间

通过 max-age 设置过期时间

'Set-Cookie': ['id=123;max-age=2','abc=456'] // 设置 id=123 的过期时间是 2s
复制代码

刷新页面,network 中 localhost

Request Headers 

    Set-Cookie: id=123;max-age=2

    Set-Cookie: abc=456

Request Headers

    Cookie: id=123; abc=456

复制代码

超过2s,再次刷新页面

Request Headers 

    Set-Cookie: id=123;max-age=2

    Set-Cookie: abc=456

Request Headers

    Cookie: abc=456 // 123 过期了,所以请求不会带上
复制代码

超过过期时间的 Cookie,浏览器发送请求时就不会带上了。

max-age 和 expires 是两种不同的写法,效果一样。expires 是到什么时间点过期。max-age 计算简单。

禁止 JS 访问 Cookie

通过 HttpOnly 禁止 JS 访问 Cookie。

开发过程中,如果涉及到安全性问题,可以考虑禁用。

'Set-Cookie': ['id=123;max-age=2','abc=456; HttpOnly'] // 给 abc=456 的 cookie 设置禁止 JS 访问
复制代码
// test.html
<script>
  console.log(document.cookie) // 通过 JS 只能拿到 id=123 了
</script>
复制代码
二级域名访问一级域名的 Cookie

通过 Cookie 的 domain 设置

Cookie 有访问域的权限设定,一般情况下,当前要访问的 Cookie 其他域是不能访问的,如 a.com 下的 Cookie,只有在 a.com 的域名下才能访问到,b.com 就不能访问。

对于同一个域名,Cookie 有更多的限制方案。a.com 有二级域名 test.a.com,可以让 test.a.com 访问到 a.com 下的 Cookie,通过 domain 的方式实现。

a.test.comb.test.com 在系统的 host 中映射成 locahost,通过 HostAdmin App 完成映射。把两个域名映射到 127.0.0.1

hosts文件无法更改解决方案,win8.1/win10无法修改编辑保存hosts文件怎么办

这样通过 a.test.com:8888 和 b.test.com:8888可以进行访问了。

a.test.com:8888 在 application 的 Cookies 下 可以看到 Cookie。

b.test.com:8888 在 application 的 Cookies 下 看不到 Cookie,因为服务端没有设置。

如何让二级域名都能访问到一级域名下的 Cookie 呢

通过 domain 来设置

// server.js
const http = require('http')
const fs = require('fs')

http.createServer(function (request, response) {
  console.log('request come', request.url)

  const host = request.headers.host

  if (request.url === '/') {
    const html = fs.readFileSync('test.html', 'utf8')
    if (host === 'test.com:8888') { // 注意这里是一级域名
      response.writeHead(200, {
        'Content-Type': 'text/html',
        'Set-Cookie': ['id=123','abc=456;domain=test.com'] // 给 abc=456 设置 domain
      })
    }
    response.end(html)
  }
}).listen(8888)

console.log('server listening on 8888')
复制代码

访问一级域名 test.com:8888 可以看到两个 Cookie。

访问二级域名 a.test.com:8888 可以看到 abc=456 的 Cookie ,并且每次请求都会带上。

Session

session 有很多种实现方法,在网站当中最经常用的是使用 Cookie 来保存 session。

把用户登录后的 Id 或者 session 的 key 设置到 Cookie 中,每个用户对应的值都不一样,当用户再次请求,服务端读取 Cookie 中的值,通过这个值拿到用户对应的唯一的 key,通过 key 来定位用户的信息,并做一系列的操作。

把用户 id 相关信息转化成对应的唯一 key,用户信息和 session key 的对应关系存在服务端的数据库或者缓存中。

请求时,服务端读取 session key ,再对应找到对应用户信息。

转载于:https://juejin.im/post/5ba5a0736fb9a05d3a4b34e5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值