session和token认证方式,cookie和localStorage存储,Web安全 ——总结

session和token认证方式,cookie和localStorage存储,Web安全 ——总结

目录

1.web服务的安全问题

1.1 XSS
1.2 CSRF
1.3 同源策略
1.4 跨域访问
1.4 cookie的安全性

2.认证方式

2.1 token和session,两种认证方式
2.2 存token的解决方案

1.web服务的安全问题

1.1 XSS

Cross Site Scripting, 简称XSS (跨站脚本攻击)。

参考:百度百科

解释: XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。 这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。

原理: HTML是一种超文本标记语言,通过将一些字符特殊地对待来区别文本和标记,例如,小于符号(<)被看作是HTML标签的开始,与之间的字符是页面的标题等等。当动态页面中插入的内容含有这些特殊字符(如<)时,用户浏览器会将其误认为是插入了HTML标签,当这些HTML标签引入了一段JavaScript脚本时,这些脚本程序就将会在用户浏览器中执行。所以,当这些特殊字符不能被动态页面检查或检查出现失误时,就将会产生XSS漏洞。

我的总结:

使用httpOnly的cookie 可以避免cookie受到XSS攻击,而没有使用httpOnly的cookie和Web Storage则容易受到XSS攻击。使用了httpOnly的cookie是js无法访问控制的(document.cookie是获取不到的),而Web Storage(例如localStorage)是可以被js访问控制的,所以从这一点来看cookie相较于Web Storage更加安全。

1.2 CSRF

Cross-site request forgery, 简称CSRF或XSRF (跨站请求伪造)。

参考:百度百科,[写bug博客]https://segmentfault.com/a/1190000015597029

解释:CSRF 是一种挟制用户在当前已登录的Web应用上执行非本意的操作的攻击方法。跟XSS相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对浏览器的信任

原理:我们都知道,当我们访问一个网站或向它发出请求时,浏览器会自动携带cookie,假如cookie中保存了登录状态信息,请看下面的例子:

1.你登录了A银行网站,用一个账号名称为Jacy的账号进行了转账操作,URL是:http://www.examplebank.com/withdraw?account=Jacy&amount=1000&for=SomeBody

2.在你还未退出A银行网站,即保存在cookie中的登录信息有效情况下,你访问了B网站,若这个B网站放入了恶意js代码:http://www.examplebank.com/withdraw?account=Jacy&amount=1000&for=Badman。 B网站在你浏览网站时在背后发送了这个请求,此时浏览器会把带有A网站登录信息的cookie发送给A银行系统,A银行系统会判断cookie认为你是登录/认证的用户,就会执行转账操作,那么你的Jacy账号将损失1000元。

我的总结:

从CSRF来看,cookie是不安全的,但现在浏览器都具备同源策略,所以这种跨域的请求就会被拒绝。若使用token认证技术并将token存在localStorage中,每次请求时从localStorage中取出token放在请求头中,则可以有效避免CSRF。所以从这一点来看localStorage的策略比cookie更安全

1.3同源策略

站点A的域名:www.aaa.com,站点B的域名:www.bbb.com。

假设前端网页是部署在A上,服务端是部署在站点B上。 现在我要从A用ajax给B发请求,这个时候B会拒绝A的请求,这个就是浏览器的同源策略。同源策略是一种保护机制,保护用户不受CSRF攻击。

那么问题来了,假如我的项目时前后端分离,那么我该怎么部署或者说怎么消除同源策略的限制?请看下面的跨域访问

1.4.跨域访问

方案一:Nginx 反向代理

这个可以参考我的另一篇博客:[待完成]

方案二:服务端设置跨域

参考博客:

[阮一峰CORS] https://www.ruanyifeng.com/blog/2016/04/cors.html

[如何设置Access-Control-Allow-Origin] https://www.jianshu.com/p/89a377c52b48

服务端设置响应头:

​ Access-Control-Allow-Origin: http://example.com

​ Access-Control-Allow-Credentials: true

前端ajax设置请求头:withCredentials : true

1.5关于cookie的安全性

参考文章

[cookie详解]https://zh.javascript.info/cookie

[同源策略、跨域和cookie的安全性]https://segmentfault.com/a/1190000015597029


2.认证方式

2.1.token和session,两种认证方式

1) session认证

后端操作cookie和session, 采用session认证技术

session和token认证方式,cookie和localStorage存储,Web安全 ——总结_第1张图片

2)token之jwt技术

JSON Web Token (JWT)是一个开放标准(RFC 7519),简单讲jwt是一项技术规范,遵循这个规范可以生成一个token,token本质就是一串字符,例如:
session和token认证方式,cookie和localStorage存储,Web安全 ——总结_第2张图片

这是一个很长的字符串,中间有.隔开,表示token是由3部分组成。(注:token字符串是不换行的,上述例子仅为了方面展示才换行显示)

这个token包含了用户的登录信息(包含用户id等,注:敏感信息是非常不建议放token里的)。客户端登录后就能拿到token,之后需要认证的请求都可以带上token发请求,服务端拿到带token的请求后验证token的正确性并判断是哪个用户。session技术是将登录信息放在服务端(服务端有状态),而token技术是将登录信息放在客户端(也就是服务端是无状态的)。

关于jwt详细分析,可以参考阮老师的博客 https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html

我认为相较于session认证,token技术的优缺点:

优点:

  • 跨域,cookie不支持跨域,token是跨域的。假若你是做公共API的,凡是在你这认证了的网站都分给他们一个token,通过这个token来跨域访问你的API
  • 传统的session方案是不支持单点登录的,而token技术可以轻松实现单点登录。
  • 更适应移动端,移动端不支持cookie。
  • 解耦,token可以在任何地方生成,调用API时生成token即可

缺点:

  • 因为需要验证token所以开销更大,占CPU资源;
  • 因为token比SessionID要大,所以更占带宽,会消耗更多流量。
  • 服务端不能直接让token失效,即在用户退出后,服务端不能让他的token失效,而是要等到token到期后自动失效。要解决这个问题除非增加服务端逻辑,比如设置token黑名单。

下面的问题值得讨论:客户端的token存哪里?

1.用localStorage存token

  • 前端登录要存token,退出后要清除token,就是说需要手动存删token,增加了维护的负担
  • localStorage存token存在XSS攻击风险

2.用cookie存token

如果是前端自己手动将cookie存token,那么问题和上面用localStorage是一样的。但是,如果是将cookie交给服务端管理,前端不能操作cookie,那么会更加安全。

2.3.存token的解决方案

参考博客:

http://blog.itpub.net/10742815/viewspace-2142725/

https://segmentfault.com/q/1010000022581000

在Web服务应用中,后端通过Set-cookie把token放在cookie中,对cookie设置httpOnly(使js不能访问cookie)。这样做也就是把token交给服务端维护,前端不用管。

我的观点:

一个完善的后端,包含了对Web网页和APP应用提供API,此时后端应该把token放在两处,当用户登录成功后,一方面通过Set-cookie设置token(供Web网页使用),另一方面在返回的json数据中放置token字段(供APP应用使用)。

1)Web服务可以采用上述的方案。

2)但在APP中则有些不同:对APP来说用户的登录状态维持时间应该更长,此时需要两个token,一个是认证用的auth_token,另一个是刷新token的refresh_token (名字不是固定的,表意即可)

APP把两个token保存在本地,每次请求需要取auth_token放置到请求头,当token失效时APP需要取refresh_token去刷新从而获得新的auth_token。其中refresh_token的有效期要比auth_token长,假设auth_token有效期是7天,则可以将refresh_token的有效期设置为14天(token的有效期也不易过长)。

你可能感兴趣的:(Web,web,session,cookie,javascript,安全)