# cookie
- name:cookie名称
- domain:cookie生效的域名
- path:cookie生效的路径
- expires:cookie过期时间
- HttpOnly
- 存储在浏览器的一段字符串
跨越不共享(额外配置)- 每次发送http请求,会将请求域的cookie一起发送给server
- server端可以修改cookie并返回给浏览器
- 浏览器也可以通过js修改cookie(有限制)
- 客户端修改cookie document.cookie='k1=1000'
document.cookie = newCookie;
newCookie是一个键值对形式的字符串。需要注意的是,用这个方法一次只能对一个cookie进行设置或更新。
以下可选的cookie属性值可以跟在键值对后,用来具体化对cookie的设定/更新,使用分号以作分隔:
- ;path=path (例如 '/', '/mydir') 如果没有定义,默认为当前文档位置的路径。
- ;domain=domain (例如 'example.com', 'subdomain.example.com') 如果没有定义,默认为当前文档位置的路径的域名部分。与早期规范相反的是,在域名前面加 . 符将会被忽视,因为浏览器也许会拒绝设置这样的cookie。如果指定了一个域,那么子域也包含在内。
- ;max-age=max-age-in-seconds (例如一年为606024*365)
- ;expires=date-in-GMTString-format 如果没有定义,cookie会在对话结束时过期
- 这个值的格式参见Date.toUTCString()
- ;secure (cookie只通过https协议传输)
# nodejs查看cookie
//设置cookie,path为/让它在整个网站都能使用,如果不加,默认在当前路径下
res.setHeader('Set-Cookie',`username=${data.username};path=/ `)
//获取cookie并且修改成对象
req.cookie={}
const cookieStr = req.headers.cookie||"";
cookieStr.split(";").forEach(item=>{
if(!item){
return
}
const arr = item.split("=");
const key = arr[0].trim();
const val = arr[1].trim();
req.cookie[key]=val
})
# cookie限制
设置 httpOnly
res.setHeader('Set-Cookie',`username=${data.username};path=/; httpOnly `)
//防止有些不应该修改的数据被客户端人为修改
# 过期时间
//获取cookie的过期时间
const getCookieExpires = () =>{
const d = new Date()
d.setTime(d.getTime()+(24*60*60*1000))
return d.toGMTString()
}
res.setHeader("Set-Cookie",`username=19998; path=/; httpOnly; expires=${getCookieExpires()}`)
# cookie的优缺点
优点: 极高的扩展性和可用性
- 数据持久性。
- 不需要任何服务器资源。 Cookie 存储在客户端并在发送后由服务器读取。
- 可配置到期规则。 偷盗者很可能拿到一个过期的 cookie 。
- 简单性。 基于文本的轻量结构。
- 通过加密和安全传输技术( SSL ),减少 cookie 被破解的可能性。
- 只在 cookie 中存放不敏感数据。
缺点:
- Cookie 数量和长度的限制 。
数量:每个域的 cookie 总数有限。
a. IE6 或更低版本最多 20 个 cookie
b. IE7 和之后的版本最后可以有 50 个 cookie
c. Firefox 最多 50 个 cookie
d. chrome 和 Safari 没有做硬性限制
长度:每个 cookie 长度不超过 4KB ( 4096B ),否则会被截掉。
- 潜在的安全风险 。 Cookie 可能被拦截、篡改。如果 cookie 被拦截,就有可能取得所有的 session 信息。
- 用户配置为禁用 。
- cookie在每次发起HTTP请求的时候都会被发送给服务器 ,一些不需要的信息也有可能会被发送,造成浪费。
# SameSite 属性值
- Strict:浏览器将只在第一方上下文中发送 Cookie(即,当从与 Cookie 的域相同的站点发起请求时)。
- Lax:浏览器将在第一方上下文和某些 GET 请求的第三方上下文中发送 Cookie(例如,通过链接点击或表单提交)。
- None:明确要求浏览器在跨站请求时发送 Cookie,但此时必须同时设置 Secure 属性(即,仅通过 HTTPS 发送)。
# secure 属性值
注意,在设置Secure属性时,必须确保你的应用是通过HTTPS协议进行通信的,否则浏览器将不会接受这个Cookie。
res.cookie('yourCookieName', 'yourCookieValue', { secure: true, httpOnly: true });
# session
让信息更加安全:cookie中存储userid等不重要的信息,server端对应重要的个人信息
const SESSION_DATA ={}
//cookie
req.cookie={}
const cookieStr = req.headers.cookie||""
cookieStr.split(";").forEach(item=>{
if(!item){
return
}
const arr=item.split("=")
const key= arr[0].trim()
req.cookie[key] = arr[1].trim()
})
let needSetCookie =false;
let userId = req.cookie.userid
if(userId){
if(!SESSION_DATA[userId]){
SESSION_DATA[userId] = {}
}
}else{
needSetCookie =true
userId =`${Date.now()}_${Math.random()}`
SESSION_DATA[userId] = {}
}
console.log(1,SESSION_DATA)
req.session =SESSION_DATA[userId]
if(needSetCookie){
res.setHeader("Set-Cookie",`userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
}
------
req.session.username = username
req.session.realname = password
- 将所有的userid传入
SESSION_DATA这个对象中,SESSION_DATA[userid] - 通过添加username+realname到SESSION_DATA[userid].username/realname中
- 当需要获取SESSION_DATA中存储的username/realname时,需要从cookie中提取userid来匹配
- 当初次登录,就得随机数生成
userid,同时种在请求中 - 当前台存储了cookie,服务重启了,则需要重设SESSION_DATA[userId] = {}