前端宝典十四:Node缓存、安全与鉴权
本文主要从Node缓存、安全与鉴权几个方面睁开解析,包含几个方面:[*]Cookie 定义、设置、生命周期以及安全性
[*]Node缓存分类和区别
[*]Node鉴权包含session、cookie、token、jwt等
一、Cookie
HTTP Cookie(通常也叫 Web Cookie 或浏览器 Cookie),是服务器发送到用户浏览器并保存在当地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。支持无状态的HTTP变为“有状态”
1、Cookie 作用:
1. 会话状态管理
如用户登录状态、购物车、游戏分数或别的需要纪录的信息
2. 个性化设置
如用户自定义设置、主题等
3. 浏览器行为跟踪
如跟踪分析用户行为等
当服务器收到 HTTP 请求时,服务器可以在响应头内里添加一个 Set-Cookie 选项。浏览器收到响应后通常会保存下 Cookie,之后对该服务器每一次请求中都通过 Cookie 请求头部将 Cookie 信息发送给服务器。
2、Set-Cookie
服务器利用 Set-Cookie 响应头部向用户代理(一样平常是浏览器)发送 Cookie 信息。一个简朴的 Cookie 大概像这样:
Set-Cookie: <cookie 名>=<cookie 值>
服务器通过该头部告知客户端保存 Cookie 信息
3、Cookie 的生命周期
Cookie 的生命周期包括:
1. 会话期 Cookie
浏览器关闭之后它会被自动删除,也就是说它仅在会话期内有用。会话期 Cookie 不需要指定过期时间(Expires)大概有用期(Max-Age);
2. 长期性 Cookie
生命周期取决于过期时间(Expires)或有用期(Max-Age);
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
4、如何保证Cookie安全性
1. Secure
表示只应通过被 HTTPS 协议加密过的请求发送给服务端;
2. HttpOnly
JavaScript Document.cookie API 无法访问带有 HttpOnly 属性的 cookie;此类 Cookie 仅作用于服务器。例如,长期化服务器端会话的 Cookie 不需要对 JavaScript 可用,而应具有 HttpOnly 属性。
HttpOnly 范例的 Cookie 用于制止了 JavaScript 对其的访问性而能在肯定程度上缓解XSS攻击。
3. SameSite Cookie
答应服务器要求某个 cookie 在跨站请求时不会被发送,从而可以制止(CSRF)。
SameSite 可以有下面三种值:
[*]None:浏览器会在同站请求、跨站请求下继续发送 cookies,不区分大小写;
[*]Strict:浏览器将只在访问雷同站点时发送 cookie;
[*]Lax:与 Strict 雷同,但用户从外部站点导航至 URL 时(例如通过链接)除外。 在新版本浏览器中,为默认选项,Same-site cookies 将会为一些跨站子请求保留,如图片加载大概 frames 的调用,但只有当用户从外部站点导航到 URL 时才会发送。如 link 链接;
cookie samesite限制 strict可缓解CSRF攻击
示例:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Secure; HttpOnly;SameSite=Strict 二、Node缓存
1、强制缓存
当客户端请求后,会先访问缓存数据库看缓存是否存在。如果存在则直接返回,不存在则请求真的服务器。
强制缓存直接淘汰请求数,是提升最大的缓存策略。 如果考虑利用缓存来优化网页性能的话,强制缓存应该是首先被考虑的。
强制缓存不需要与服务器发生交互。
https://i-blog.csdnimg.cn/direct/1aed5ba0f9cf446f9b26795286fe430e.png#pic_center
可以造成强制缓存的字段是 Cache-control 和 Expires
但是Expires设置的绝对时间,欠好用,如果客户端修改当地时间,cookie失效
全部要利用Cache-control,Cache-control这是的相对时间
// 表示有用时间为20s
Cache-control: max-age=20
cache-control设置:
[*]no-cache:相称于需要利用协商缓存,克制利用强制缓存;
[*]no-store:相称于不利用强制缓存和协商缓存;
[*]public 任何路径的缓存者(当地缓存、代理服务器),可以无条件的缓存改资源,不设置默认为public;
[*]private 只针对单个用户大概实体(差别用户、窗口)缓存资源;
2、协商缓存也叫对比缓存
当强制缓存失效(超过规定时间)时,就需要利用对比缓存,由服务器决定缓存内容是否失效。对比缓存是可以和强制缓存一起利用。
1. last-modified
缺点:
[*]last-modified是以秒为单位的,假如资料在1s内大概修改几次,那么该缓存就不能被利用的;
[*]如果文件是通过服务器动态天生,那么更新的时间永久就是天生的时间,尽管文件大概没有变革,所以起不到缓存的作用;
2. Etag
Etag是根据文件内容,算出一个唯一的值。服务器存储着文件的 Etag 字段。
之后的流程和 Last-Modified 一致,只是 Last-Modified 字段和它所表示的更新时间改变成了 Etag 字段和它所表示的文件 hash,把 If-Modified-Since 变成了 If-None-Match。
服务器同样进行比力,掷中返回 304, 不掷中返回新资源和 200。 Etag 的优先级高于 Last-Modified
缺点:
[*]每次请求的时间,服务器都会把文件读取一次,以确认文件有没有修改;
[*]大文件进行etag 一样平常用文件的大小 + 文件的末了修改时间 来组合天生这个etag;
三、Node鉴权
现在常用的鉴权有四种:
[*]HTTP Basic Authentication
[*]session-cookie
[*]Token 验证
[*]OAuth(开放授权)
这里主要讨论session-cookie和Token 验证
1、session-cookie
session 是缓存在服务端的,cookie 则是缓存在客户端,他们都由服务端天生,为了弥补 Http 协议无状态的缺陷。
1.session-cookie认证
[*]服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(我们可以将seesion保存在 内存中,也可以保存在redis中,保举利用后者),然后给这个session天生一个唯一的标识字符串,然后在 response header 中种下这个唯一标识字符串;
[*]签名。这一步通过秘钥对sid进行签名处置惩罚,避免客户端修改sid;(非必须步骤)
[*]浏览器中收到请求响应的时间会解析响应头,然后将sid保存在当地cookie中,浏览器在下次http请求的请求头中会带上该域名下的cookie信息。
[*]服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客户端的session,然后判断该请求是否合法。
https://i-blog.csdnimg.cn/direct/537c7461c1de4213b2337766e0d02c05.png#pic_center
2.实例:用户登录认证
利用session-cookie做登录认证时,登录时存储session,退出登录时删除session,而其他的需要登录后才气操作的接口需要提前验证是否存在session,存在才气跳转页面,不存在则回到登录页面。
[*]在koa中做一个验证的中间件,在需要验证的接口中利用该中间件。
//前端代码
async login() {
await axios.post('/login', {
username: this.username,
password: this.password
})
},
async logout() {
await axios.post('/logout')
},
async getUser() {
await axios.get('/getUser')
}
//中间件 auth.js
module.exports = async (ctx, next) => {
if (!ctx.session.userinfo) {
ctx.body = {
ok: 0,
message: "用户未登录" };
} else {
await next();
}
};
//需要验证的接口
router.get('/getUser', require('auth'), async (ctx) => {
ctx.body = {
message: "获取数据成功",
userinfo: ctx.session.userinfo
}
})
//登录
router.post('/login', async (ctx) => {
const {
body
} = ctx.request
console.log('body', body)
//设置session
ctx.session.userinfo = body.username;
ctx.body = {
message: "登录成功"
}
})
//登出
router.post('/logout', async (ctx) => {
//设置session
delete ctx.session.userinfo
ctx.body = {
message: "登出系统"
}
})
2、Token
token 是一个令牌,浏览器第一次访问服务端时会签发一张令牌,之后浏览器每次携带这张令牌访问服务端就会认证该令牌是否有用,只要服务端可以解密该令牌,就阐明请求是合法的,令牌中包含的用户信息还可以区分差别身份的用户。一样平常 token 由用户信息、时间戳和由 hash 算法加密的签名构成。
1. Token认证流程
[*]客户端利用用户名跟暗码请求登录;
[*]服务端收到请求,去验证用户名与暗码;
[*]验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端;
[*]客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里大概Local Storage 里;
[*]客户端每次向服务端请求资源的时间需要带着服务端签发的 Token;
[*]服务端收到请求,然后去验证客户端请求内里带着的 Token(request头部添加Authorization),如果验证成功,就向客户端返回请求的数据 ,如果不成功返回401错误码,鉴权失败;
2. Token和session的区别
session-cookie的缺点:
[*]认证方式范围于在浏览器中利用,cookie 是浏览器端的机制,如果在app端就无法利用 cookie;
[*]为了满足全局一致性,我们最好把 session 存储在 redis 中做长期化,而在分布式环境下,我们大概需要在每个服务器上都备份,占用了大量的存储空间;
[*]在不是 Https 协议下利用 cookie ,容易受到 CSRF 跨站点请求伪造攻击。
3. token的缺点:
[*]加密解密消耗使得 token 认证比 session-cookie 更消耗性能;
[*]token 比 sid 大,更占带宽;
4. token与cookie的区别
[*]token 认证不范围于 cookie ,这样就使得这种认证方式可以支持多种客户端,而不但是浏览器。且不受同源策略的影响;
[*]不利用 cookie 就可以规避CSRF攻击;
[*]token 不需要存储,token 中已包含了用户信息,服务器端变成无状态,服务器端只需要根据定义的规则校验这个 token 是否合法就行。这也使得 token 的可扩展性更强。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]