1、无状态的HTTP协议:
协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。
HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。
2、会话(Session)跟踪:
会话,指用户登录网站后的一系列动作,比如浏览商品添加到购物车并购买。会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。
常用的会话跟踪技术是Cookie与Session。
Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
什么是Session?
1.由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了
2.Session用于标识这个用户,并且跟踪用户,Session是保存在服务端的,有一个唯一标识。在服务端保存Session的方法很多,内存、数据库、文件都有。
3.大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候Session信息都是放在内存的,使用一些缓存服务比如Memcached之类的来放Session。
每个用户访问服务器都会建立一个session,那服务器是怎么标识用户的唯一身份呢?
事实上,用户与服务器建立连接的同时,服务器会自动为其分配一个SessionId。
什么东西可以让你每次请求都把SessionId自动带到服务器呢?
显然就是cookie了,如果你想为用户建立一次会话,可以在用户授权成功时给他一个唯一的cookie。当一个用户提交了表单时,浏览器会将用户的SessionId自动附加在HTTP头信息中,当服务器处理完这个表单后,将结果返回给SessionId所对应的用户。
储存需要的信息。服务器通过SessionId作为key,读写到对应的value,这就达到了保持会话信息的目的。
session的创建:
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了sessionId
如果已包含则说明以前已经为此客户端创建过session,服务器就按照sessionId把这个session检索出来使用(检索不到,会新建一个)
如果客户端请求不包含sessionId,则为此客户端创建一个session并且生成一个与此session相关联的sessionId
sessionId的值是一个既不会重复,又不容易被找到规律以仿造的字符串,这个sessionId将被在本次响应中返回给客户端保存。
禁用cookie:如果客户端禁用了cookie,通常有两种方法实现session而不依赖cookie。
1)URL重写,就是把sessionId直接附加在URL路径的后面。
2)表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如:
Session共享:
对于多网站(同一父域不同子域)单服务器,我们需要解决的就是来自不同网站之间SessionId的共享。
由于域名不同(aaa.test.com和bbb.test.com),而SessionId又分别储存在各自的cookie中,因此服务器会认为对于两个子站的访问,是来自不同的会话。
解决的方法是通过修改cookies的域名为父域名达到cookie共享的目的,从而实现SessionId的共享。带来的弊端就是,子站间的cookie信息也同时被共享了。
如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
什么是cookie?
Cookie是识别客户端的特定用户。是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
1.每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。大多数的应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 ookie里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,它就知道你是谁了。
2.如果客户端的浏览器禁用了Cookie ,一般这种情况下,会使用URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
3.Cookie还可以用在一些方便用户的场景下,登陆过一个网站,下次登录的时候不想再次输入账号了,这个信息就可以写到Cookie里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了。
使用基于 Cookie 的身份验证方法,流程是这样的:
①用户登录,输入账号密码
②服务器验证用户账号密码正确,创建一个 session 存储在数据库(或者 redis)
③将 session ID 放进 cookie 中,被存储在用户浏览器中。
④再次发起请求,服务器直接通过 session ID 对用户进行验证
⑤一旦用户登出,则 session 在客户端和服务器端都被销毁
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端会把Cookie保存起来。
当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围。
1)Name 和 Value 属性由程序设定,默认值都是空引用。
2)Domain属性的默认值为当前URL的域名部分,不管发出这个cookie的页面在哪个目录下的。
3)Path属性的默认值是根目录,即 ”/” ,不管发出这个cookie的页面在哪个目录下的。可以由程序设置为一定的路径来进一步限制此cookie的作用范围。
4)Expires属性,这个属性设置此Cookie 的过期日期和时间。
会话Cookie和持久Cookie
若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。
会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。
若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。
存储在硬盘上的cookie可以在浏览器的不同进程间共享。这种称为持久Cookie。
Cookie具有不可跨域名性,就是说,浏览器访问百度不会带上谷歌的cookie。
什么是token?
oken的意思是“令牌”,是用户身份的验证方式。
最简单的token组成:uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,由token的前几位+盐以哈希算法压缩成一定长的十六进制字符串,可以防止恶意第三方拼接token请求服务器)。还可以把不变的参数也放进token,避免多次查库
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:
①客户端使用用户名跟密码请求登录
②服务端收到请求,去验证用户名与密码
③验证成功后,服务端会签发一个Token,再把这个Token发送给客户端
④客户端收到 Token 以后可以把它存储起来,比如放在Cookie里
⑤客户端每次向服务端请求资源的时候需要带着服务端签发的Token
⑥服务端收到请求,然后去验证客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据
例如:APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码
如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,
以后APP请求时,凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,
失败返回错误信息,让他重新登录。
其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。
1.服务器上的token存储到数据库中,每次查询会不会很费时。如果不存储到数据库,应该存储到哪里呢?
2.客户端得到的token肯定要加密存储的,发送token的时候再解密。存储到数据库还是配置文件呢?
token是个易失数据,丢了无非让用户重新登录一下
token是个凭条,token丢了重新操作下认证一个就可以了,因此token丢失的代价是可以忍受的——前提是你别丢太频繁,要是让用户隔三差五就认证一次那就损失用户体验了。
基于这个出发点,如果你认为用数据库来保持token查询时间太长,会成为你系统的瓶颈或者隐患,可以放在内存当中。
比如memcached、redis,KV方式很适合token查询的需求。
客户端方面除非有一个非常安全的办法,比如操作系统提供的隐私数据存储,那token肯定会存在泄露的问题。
比如我拿到你的手机,把你的token拷出来,在过期之前就都可以以你的身份在别的地方登录。
解决这个问题的一个简单办法
1、在存储的时候把token进行对称加密存储,用时解开。
2、将请求URL、时间戳、token三者进行合并加签签名,服务端校验有效性。
在网络层面上token明文传输的话会非常的危险,所以建议一定要使用HTTPS,并且把token放在post body里。
cookie和token的区别
token优势在于,Token 可以是无状态的,可以在多个服务间共享。Token 可以避免 CSRF 攻击。
token由于服务器端不存储会话,所以可扩展性强,token还可用于APP中
token和cookie一样都是首次登陆时,由服务器下发,都是当交互时进行验证的功能,作用都是为无状态的HTTP提供的持久机制。
cookie和session的区别总结:
1:cookie数据存放再浏览器中,session储存再服务器中。
2:cookie安全性不高,别人可以分析存放在本地的cookie并进行cookie欺骗。
3:session访问增多,会比较占用服务器的性能。
4:单个cookie保存的数据不会超过4k,很多浏览器都限制一个站点最多保存20个cookie。
5:可以考虑将登陆信息等重要信息存放为session,其他信息需要保留,可以存放在cookie中。
CSRF(Cross-site request forgery)跨站请求伪造。是劫持受信任用户向服务器发送非预期请求的攻击方式。例如,这些非预期请求可能在url后加入一些恶意的参数,从而达到攻击者的目的。
目前防御 CSRF 攻击主要有三种策略:验证 HTTP Referer 字段;在请求地址中添加 token 并验证;在 HTTP 头中自定义属性并验证。
XSS攻击全称跨站脚本攻击,是一种网站应用程序的安全漏洞攻击,是代码注入的一种
一、是在表单提交或者url参数传递前,对需要的参数进行过滤,过滤非法字符:
二、 过滤用户输入的 检查用户输入的内容中是否有非法内容。如<>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)等。严格控制输出
XSS:通过客户端脚本语言(最常见如:JavaScript)在一个论坛发帖中发布一段恶意的JavaScript代码就是脚本注入,如果这个代码内容有请求外部服务器,那么就叫做XSS!
CSRF:又称XSRF,冒充用户发起请求(在用户不知情的情况下),完成一些违背用户意愿的请求(如恶意发帖,删帖,改密码,发邮件等)。
CSRF 和 XSS 的区别
区别一:
CSRF:需要用户先登录网站A,获取 cookie。
XSS:不需要登录。
区别二:(原理的区别)
CSRF:是利用网站A本身的漏洞,去请求网站A的api。
XSS:是向网站 A 注入 JS代码,然后执行 JS 里的代码,篡改网站A的内容