此文主题和脉络结构如下: Cookie和Session HTTP协议是一种无状态协议,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;Session和Cookie的主要目的就是为了弥补HTTP的无状态特性。Session是什么 客户端请求服务端,服务端会为这次请求开辟一块内存空间,这个对象便是Session对象,存储结构为ConcurrentHashMap。Session弥补了HTTP无状态特性,服务器可以利用Session存储客户端在同一个会话期间的一些操作记录。Session如何判断是否是同一会话 服务器第一次接收到请求时,开辟了一块Session空间(创建了Session对象),同时生成一个sessionId,并通过响应头的SetCookie:JSESSIONIDXXXXXXX命令,向客户端发送要求设置Cookie的响应;客户端收到响应后,在本机客户端设置了一个JSESSIONIDXXXXXXX的Cookie信息,该Cookie的过期时间为浏览器会话结束; 接下来客户端每次向同一个网站发送请求时,请求头都会带上该Cookie信息(包含sessionId),然后,服务器通过读取请求头中的Cookie信息,获取名称为JSESSIONID的值,得到此次请求的sessionId。Session的缺点 Session机制有个缺点,比如A服务器存储了Session,就是做了负载均衡后,假如一段时间内A的访问量激增,会转发到B进行访问,但是B服务器并没有存储A的Session,会导致Session的失效。Cookies是什么 HTTP协议中的Cookie包括WebCookie和浏览器Cookie,它是服务器发送到Web浏览器的一小块数据。服务器发送到浏览器的Cookie,浏览器会进行存储,并与下一个请求一起发送到服务器。通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态。 HTTPCookie机制是HTTP协议无状态的一种补充和改良 Cookie主要用于下面三个目的会话管理 登陆、购物车、游戏得分或者服务器应该记住的其他内容个性化 用户偏好、主题或者其他设置追踪 记录和分析用户行为 Cookie曾经用于一般的客户端存储。虽然这是合法的,因为它们是在客户端上存储数据的唯一方法,但如今建议使用现代存储API。Cookie随每个请求一起发送,因此它们可能会降低性能(尤其是对于移动数据连接而言)。创建Cookie 当接收到客户端发出的HTTP请求时,服务器可以发送带有响应的SetCookie标头,Cookie通常由浏览器存储,然后将Cookie与HTTP标头一同向服务器发出请求。SetCookie和Cookie标头 SetCookieHTTP响应标头将cookie从服务器发送到用户代理。下面是一个发送Cookie的例子 此标头告诉客户端存储Cookie 现在,随着对服务器的每个新请求,浏览器将使用Cookie头将所有以前存储的Cookie发送回服务器。 有两种类型的Cookies,一种是SessionCookies,一种是PersistentCookies,如果Cookie不包含到期日期,则将其视为会话Cookie。会话Cookie存储在内存中,永远不会写入磁盘,当浏览器关闭时,此后Cookie将永久丢失。如果Cookie包含有效期,则将其视为持久性Cookie。在到期指定的日期,Cookie将从磁盘中删除。 还有一种是Cookie的Secure和HttpOnly标记,下面依次来介绍一下会话Cookies 上面的示例创建的是会话Cookie,会话Cookie有个特征,客户端关闭时Cookie会删除,因为它没有指定Expires或MaxAge指令。 但是,Web浏览器可能会使用会话还原,这会使大多数会话Cookie保持永久状态,就像从未关闭过浏览器一样。永久性Cookies 永久性Cookie不会在客户端关闭时过期,而是在特定日期(Expires)或特定时间长度(MaxAge)外过期。例如SetCookie:ida3fWa;ExpiresWed,21Oct201507:28:00GMT;Cookie的Secure和HttpOnly标记 安全的Cookie需要经过HTTPS协议通过加密的方式发送到服务器。即使是安全的,也不应该将敏感信息存储在cookie中,因为它们本质上是不安全的,并且此标志不能提供真正的保护。 HttpOnly的作用会话Cookie中缺少HttpOnly属性会导致攻击者可以通过程序(JS脚本、Applet等)获取到用户的Cookie信息,造成用户Cookie信息泄露,增加攻击者的跨站脚本攻击威胁。HttpOnly是微软对Cookie做的扩展,该值指定Cookie是否可通过客户端脚本访问。如果在Cookie中没有设置HttpOnly属性为true,可能导致Cookie被窃取。窃取的Cookie可以包含标识站点用户的敏感信息,如ASP。NET会话ID或Forms身份验证票证,攻击者可以重播窃取的Cookie,以便伪装成用户或获取敏感信息,进行跨站脚本攻击等。Cookie的作用域 Domain和Path标识定义了Cookie的作用域:即Cookie应该发送给哪些URL。 Domain标识指定了哪些主机可以接受Cookie。如果不指定,默认为当前主机(不包含子域名)。如果指定了Domain,则一般包含子域名。 例如,如果设置Domainmozilla。org,则Cookie也包含在子域名中(如developer。mozilla。org)。 例如,设置Pathdocs,则以下地址都会匹配:docsdocsWebdocsWebHTTPJSONWebToken和SessionCookies的对比 JSONWebToken,简称JWT,它和Session都可以为网站提供用户的身份认证,但是它们不是一回事。 下面是JWT和Session不同之处的研究JWT和SessionCookies的相同之处 在探讨JWT和SessionCookies之前,有必要需要先去理解一下它们的相同之处。 它们既可以对用户进行身份验证,也可以用来在用户单击进入不同页面时以及登陆网站或应用程序后进行身份验证。 如果没有这两者,那你可能需要在每个页面切换时都需要进行登录了。因为HTTP是一个无状态的协议。这也就意味着当你访问某个网页,然后单击同一站点上的另一个页面时,服务器的内存中将不会记住你之前的操作。 因此,如果你登录并访问了你有权访问的另一个页面,由于HTTP不会记录你刚刚登录的信息,因此你将再次登录。 JWT和SessionCookies就是用来处理在不同页面之间切换,保存用户登录信息的机制。 也就是说,这两种技术都是用来保存你的登录状态,能够让你在浏览任意受密码保护的网站。通过在每次产生新的请求时对用户数据进行身份验证来解决此问题。 所以JWT和SessionCookies的相同之处是什么?那就是它们能够支持你在发送不同请求之间,记录并验证你的登录状态的一种机制。什么是SessionCookies SessionCookies也称为会话Cookies,在SessionCookies中,用户的登录状态会保存在服务器的内存中。当用户登录时,Session就被服务端安全的创建。 在每次请求时,服务器都会从会话Cookie中读取SessionId,如果服务端的数据和读取的SessionId相同,那么服务器就会发送响应给浏览器,允许用户登录。 什么是JsonWebTokens JsonWebToken的简称就是JWT,通常可以称为Json令牌。它是RFC7519中定义的用于安全的将信息作为Json对象进行传输的一种形式。JWT中存储的信息是经过数字签名的,因此可以被信任和理解。可以使用HMAC算法或使用RSAECDSA的公用专用密钥对JWT进行签名。 使用JWT主要用来下面两点认证(Authorization):这是使用JWT最常见的一种情况,一旦用户登录,后面每个请求都会包含JWT,从而允许用户访问该令牌所允许的路由、服务和资源。单点登录是当今广泛使用JWT的一项功能,因为它的开销很小。信息交换(InformationExchange):JWT是能够安全传输信息的一种方式。通过使用公钥私钥对JWT进行签名认证。此外,由于签名是使用head和payload计算的,因此你还可以验证内容是否遭到篡改。JWT的格式 下面,我们会探讨一下JWT的组成和格式是什么 JWT主要由三部分组成,每个部分用。进行分割,各个部分分别是HeaderPayloadSignature 因此,一个非常简单的JWT组成会是下面这样 然后我们分别对不同的部分进行探讨。 Header Header是JWT的标头,它通常由两部分组成:令牌的类型(即JWT)和使用的签名算法,例如HMACSHA256或RSA。 例如{alg:HS256,typ:JWT} 指定类型和签名算法后,Json块被Base64Url编码形成JWT的第一部分。 Payload Token的第二部分是Payload,Payload中包含一个声明。声明是有关实体(通常是用户)和其他数据的声明。共有三种类型的声明:registered,public和private声明。registered声明:包含一组建议使用的预定义声明,主要包括 ISS 签发人 iss(issuer) 签发人 exp(expirationtime) 过期时间 sub(subject) 主题 aud(audience) 受众 nbf(NotBefore) 生效时间 iat(IssuedAt) 签发时间 jti(JWTID) 编号public声明:公共的声明,可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息,但不建议添加敏感信息,因为该部分在客户端可解密。private声明:自定义声明,旨在在同意使用它们的各方之间共享信息,既不是注册声明也不是公共声明。 例如{sub:1234567890,name:JohnDoe,admin:true} 然后payloadJson块会被Base64Url编码形成JWT的第二部分。 signature JWT的第三部分是一个签证信息,这个签证信息由三部分组成header(base64后的)payload(base64后的)secret 比如我们需要HMACSHA256算法进行签名HMACSHA256(base64UrlEncode(header)。base64UrlEncode(payload),secret) 签名用于验证消息在此过程中没有更改,并且对于使用私钥进行签名的令牌,它还可以验证JWT的发送者的真实身份拼凑在一起 现在我们把上面的三个由点分隔的Base64URL字符串部分组成在一起,这个字符串可以在HTML和HTTP环境中轻松传递这些字符串。 下面是一个完整的JWT示例,它对header和payload进行编码,然后使用signature进行签名eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9。eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9。TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 如果想自己测试编写的话,可以访问JWT官网https:jwt。iodebuggerioJWT和SessionCookies的不同 JWT和SessionCookies都提供安全的用户身份验证,但是它们有以下几点不同密码签名 JWT具有加密签名,而SessionCookies则没有。JSON是无状态的 JWT是无状态的,因为声明被存储在客户端,而不是服务端内存中。 身份验证可以在本地进行,而不是在请求必须通过服务器数据库或类似位置中进行。这意味着可以对用户进行多次身份验证,而无需与站点或应用程序的数据库进行通信,也无需在此过程中消耗大量资源。可扩展性 SessionCookies是存储在服务器内存中,这就意味着如果网站或者应用很大的情况下会耗费大量的资源。由于JWT是无状态的,在许多情况下,它们可以节省服务器资源。因此JWT要比SessionCookies具有更强的可扩展性。JWT支持跨域认证 SessionCookies只能用在单个节点的域或者它的子域中有效。如果它们尝试通过第三个节点访问,就会被禁止。如果你希望自己的网站和其他站点建立安全连接时,这是一个问题。 使用JWT可以解决这个问题,使用JWT能够通过多个节点进行用户认证,也就是我们常说的跨域认证。JWT和SessionCookies的选型 我们上面探讨了JWT和Cookies的不同点,相信你也会对选型有了更深的认识,大致来说 对于只需要登录用户并访问存储在站点数据库中的一些信息的中小型网站来说,SessionCookies通常就能满足。 如果你有企业级站点,应用程序或附近的站点,并且需要处理大量的请求,尤其是第三方或很多第三方(包括位于不同域的API),则JWT显然更适合。后记 前两天面试的时候问到了这个题,所以写篇文章总结一下,还问到了一个面试题,禁用Cookies,如何使用Session?网上百度了一下,发现这是PHP的面试题。。。。。。 但还是选择了解了一下,如何禁用Cookies后,使用Session如果禁用了Cookies,服务器仍会将sessionId以cookie的方式发送给浏览器,但是,浏览器不再保存这个cookie(即sessionId)了。如果想要继续使用session,需要采用URL重写的方式来实现,可以参考https:www。cnblogs。comRenyiFanp11012086。html 如果文章对你有帮助,求各位看官点点个三连!!!