博客项目登录(cookie)

cookie 介绍

  1. cookie是存储在浏览器的一段字符串(最大5kb)
  2. 跨域不共享
    • 比如:你同时打开了淘宝和百度,那么淘宝和百度对应的是2个cookie,他们是不共享的。
  3. 格式如k1=v1;k2=v2;k3=v3;因此可以存储结构化数据
  4. 每次发送http请求,会将请求域的cookie一起发送给server端
    • 比如:你在淘宝中请求访问百度,那么就会将百度的cookie发送给server端。例子
  5. server端可以修改cookie并返回给浏览器
  6. 浏览器中也可以通过javascript修改cookie(有限制)

客户端JS操作cookie

客户端(浏览器)查看cookie的三种方式

  1. 方式1 f12-Network:
    • 客户端通过请求头将cookie传给服务端:请求头中的cookie
    • 服务端将处理好的cookie通过响应头返回给客户端:响应头中的cookie
    • 接下来客户端就可以使用服务端返回的cookie。
  2. 方式2 f12-Application-Cookies-找到对应域名:
    • 这里面是解析过的cookie值:方式2
    • path为/即该网页下cookie都生效,不管是https://www.baidu.com/还是https://www.baidu.com/???xxx/yyy
    • 手动删除cookie可手动删除cookie
  3. 方式3 通过JS查看(有限制):方式3

JS查看、累加cookie(有限制)

  • 可以通过JS查看cookie(上面的方式3),也可以累加cookie(有限制),但不能删除cookie
  • 累加cookie和查看cookie的方法一样例子
  • 但其实有了本地存储Local Storage后,js修改cookie变得很少:本地存储Local Storage

server端nodejs操作cookie

获取cookie

在server端可通过req.headers.cookie获取到cookie(req是http请求),因为cookie是保存在请求头部的。

操作cookie

server端可以将cookie通过res的setHeader方法设置到响应报文头部的Set-Cookie中,比如(res是http响应报文):

1
res.setHeader(`Set-Cookie`, `username=${data.username}; path=/`);

cookie用于登录验证

app.js获取cookie转为对象

blog-1中app.js,解析cookie,cookie为字符串,不好操作,所以将其转换为对象后放到req身上方便调用:
blog-1中app.js解析cookie

  1. 使用字符串的split方法将字符串分隔为数组
  2. 使用数组的forEach方法将每个数组元素都分隔后放入对象中作为属性和属性值

测试:刷新页面,获取到请求中的cookie并打印出来:
测试

router-user.js创建测试登录验证的路由

  1. ctrl+shift+a+f将所有logincheck改为login:将所有logincheck改为login
  2. 创建一个路由用于测试登录验证测试登录验证的路由
    • app.js需要路由返回一个Promise对象,所以使用Promise.resolve()来快速创建一个Promise对象。
    • 测试测试结果测试结果

router-user.js测试登录

  1. 暂时将登录改为get,方便测试router-user.js
  2. 操作cookie操作cookie
  3. 测试:
    • 成功设置cookie
    • 成功登录

解决cookie的属性前有空格的问题

注意:如果原本就有cookie则无法登录成功,因为后面加入的username字符串前出现空格,导致无法获取username:
对比

解决方法:在app.js中,解析cookie时,使用字符串的trim()删除字符串的头尾空格,这样就能获取到username:
使用字符串的trim()

字符串的trim()
  • 字符串的trim()删除字符串的头尾空格
  • 不会改变原始字符串

server端给JS操作cookie做限制

  • 要给JS操作cookie做限制,cookie中某些数据是不能修改的。
  • 后端设置cookie时加上httpOnly即可,表示只允许后端修改

为什么要做限制

因为此时前端可修改cookie中的username,不安全:
前端可修改username


给cookie做限制

router-user.js中,设置cookie时加上httpOnly即可,表示只允许后端修改
加上`httpOnly`

测试:

  1. 传入username和password测试
  2. 通过测试路由可看到httpOnly设置成功httpOnly设置成功
  3. 此时前端无法获取username,修改不会报错也不会成功:前端无法获取username
  4. 修改username增添的只是假数据:前端无法真正修改cookie

设置cookie过期时间(expires)

可以看到此时cookie是不会过期的:
可以看到此时cookie是不会过期的

  1. router-user.js中,给cookie加属性expires,设置24小时后过期:router-user.js
    • toGMTString() 方法可根据格林威治时间 (GMT) 把 Date 对象转换为字符串,并返回结果。
    • 不赞成使用此toGMTString方法。请使用 toUTCString() 取而代之!!得到的结果是一样的:toUTCString() 取而代之
  2. 测试:测试
    • toGMTString打印结果:toGMTString打印结果