系统开发系列 之web开发中cookiesession和token的使用
Posted 琅晓琳
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了系统开发系列 之web开发中cookiesession和token的使用相关的知识,希望对你有一定的参考价值。
1 介绍
客户端与服务端请求响应的关系:
USER(客户端) 请求 tomcat(服务器), 属于HTTP请求。http请求是无状态的,即每次服务端接收到客户端的请求时,都是一个全新的请求,服务器并不知道客户端的历史请求记录;所以当用户从客户端请求一次登录后,登录成功,再次进行请求时,因为tomcat不能识别这两次会话都是来自同一个浏览器,即服务端不知道客户端的历史请求记录;就会再次弹出登录对话框。
会话:可以理解为用户打开浏览器,访问该web服务器的多个资源,然后关闭浏览器,这中间的一系列过程称之为一个会话。
有状态的会话:浏览器发送的每一次请求,每一个会话都要有唯一的标识来唯一标识自己,当浏览器发送请求的时候就带上这个标识来让服务器识别,从而实现有“状态”的会话。
javaweb中有两种实现会话的机制:
(1)Cookie机制
(2)Session机制
2 基本原理
当用户发送一个请求到服务器端时,服务器会先检查请求中是否含有sessionid(存在cookie中或者在url中)。
如果不存在sessionid(说明是第一次请求),就会为该请求用户创建一个session对象,并将该session对象的sessionid(放到响应头的set-cookie中,格式set-cookie:sessionid,下次再请求时cookie中就会有一个name为jsessionid的cookie,value就是sessionid)响应给客户端。
如果存在sessionid,就会在服务器端查找是否有该sessionid对应的session,如果有就使用,没有就创建一个。
服务器端的session和客户端的cookie是息息相关的,若是没有了cookie,又不做其他处理的话,服务器端的session也没了。
3 cookie机制
基本介绍:
1)cookie机制采用的是在客户端保持 HTTP状态信息的方案。当浏览器访问WEB服务器的某个资源时,WEB服务器会在HTTP响应头中添加一个键值对传送给浏览器,再由浏览器将该cookie放到客户端磁盘的一个文件中,该文件可理解为cookie域(键值对的集合),往后每次访问某个网站时,都会在请求头中带着这个网站的所有cookie值。(至于怎么区分不同网站的cookie的,很简单,每个网站都给他一个唯一标识比如网址等,每次打开某网址时,就查询该网站下的所有cookie值即可)。
2)每一个cookie都有一个name和一个value,且name是唯一的。相同名字时,后者会覆盖掉前者(类似哈希表的key的效果)。
3)一个WEB浏览器也可以存储多个WEB站点提供的Cookie。浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
分类:
1)会话级别的cookie
默认情况下它是一个会话级别的cookie,存储在浏览器的内存中,用户退出浏览器之后被删除。
2)持久化的cookie
若希望浏览器将该cookie存储在磁盘上,则需要设置该cookie的生命周期setMaxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
cookie的作用域:
cookie的domain和path属性定义了cookie的作用范围,即访问哪些网站或url时,会自动的带着该cookie。domain即域名,默认是当前主机(不包括子域名),path默认是*(所有路径),即域名后面的的路径。大部分情况下我们都是使用默认的设置即可。
基本原理:
当一个浏览器访问某web服务器时,web服务器会调用HttpServletResponse的addCookie()方法,在响应头中添加一个名叫Set-Cookie的响应字段用于将Cookie返回给浏览器,当浏览器第二次访问该web服务器时会自动的将该cookie回传给服务器,来实现用户状态跟踪。
4 session机制
基本介绍:
session机制采用的是在服务器端保持HTTP状态信息的方案。为了加速session的读取和存储,web服务器中会开辟一块内存用来保存服务器端所有的session,每个session都会有一个唯一标识sessionid,根据客户端传过来的jsessionid(cookie中),找到对应的服务器端的session。为了防止服务器端的session过多导致内存溢出,web服务器默认会给每个session设置一个有效期,(30分钟)若有效期内客户端没有访问过该session,服务器就认为该客户端已离线并删除该session。
保存sessionID的方式:
1)cookie中
通过一个特殊的cookie,name为JSESSIONID,value为服务器端某个 session的ID,默认的方式。但是当浏览器禁用cookie后session就会失效。
2)url重写
当浏览器Cookie被禁时用。就是把session的id附加在URL路径的后面。附加的方式也有两种,一种是作为URL路径的附加信息,另一种是作为查询字符串附加在URL后面。
5 常用API
getId()方法:得到sessionid。
invalidate()方法:让session立刻失效。
getAttribute(String key):根据key获取该session中的value。
setAttribute(String key,Object value):往session中存放key-value。
removeAttribute(Stringkey):根据key删除session中的key-value。
getServletContext():得到ServletContext。
setMaxInactiveInterval(long timeout)/getMaxInactiveInterval:设置/获取session的最大有效时间。
getCreationTime方法:获取session的创建的时间。
getLastAccessedTime方法:获取session最后一次访问的时间。
getSession():从HttpServletRequest中获取session。
6 token
基本介绍:
token,可以翻译成"令牌",本质上它是一个全局唯一的字符串,用来唯一识别一个客户端。但它不像cookie和session一样是一种web规范,个人认为他是借鉴了cookie和session工作的原理,进而延伸出来的一种维持用户会话状态的机制。
token解决了什么问题:
token解决了session依赖于单个Web服务器的问题。单体应用时用户的会话信息保存在session中,session存在于服务器端的内存中,由于前前后后用户只针对一个web服务器,所以没啥问题。但是一到了web服务器集群的环境下(我们一般都是用nginx做负载均衡,若是使用了轮询等这种请求分配策略),就会导致用户小a在A服务器登录了,session存在于A服务器中,但是第二次请求被分配到了B服务器,由于B服务器中没有用户小a的session会话,导致用户小a还要再登陆一次,以此类推。这样用户体验很不好。当然解决办法也有很多种,比如同一个用户分配到同一个服务处理、使用cookie保持用户会话信息等。
token机制下的认证流程:
1)用户登录进行身份认证,认证成功后服务器端生成Token返回给客户端;
2)客户端接收到Token后保存在客户端(可保存在Cookie、LocalStorage、SessionStorage中);
3)客户端再次请求服务器端时,将Token作为请求头放入Headers中;
4)服务器端接收请求头中的Token,将用户参数按照既定规则再进行一次签名,两次签名若一致则认为成功,反之数据存在篡改请求失败。
参考资料:
https://blog.csdn.net/qq_40925189/article/details/107030620?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165387015116782391826872%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=165387015116782391826872&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-107030620-null-null.142v11pc_search_result_control_group,157v12control&utm_term=session&spm=1018.2226.3001.4187 做web开发,怎么能不懂cookie、session和token呢?
https://blog.csdn.net/qq_28296925/article/details/80921585 session与cookie之间的关系
以上是关于系统开发系列 之web开发中cookiesession和token的使用的主要内容,如果未能解决你的问题,请参考以下文章
Springboot 系列Spring Boot web 开发之静态资源和模版引擎