一、会话跟踪
在一个浏览器的会话保持期间,可以多次请求和响应数据,但因为http协议是无状态的,每一次的请求或响应都是一次新的操作,所以必须识别哪些请求来自同一个浏览器,以便共享资源数据
比如登录一次后,再次登录时就不用再次登录了
实现方法:
1.Cookie
cookie保存在客户端浏览器中,是键值对格式存储信息,我们可以在cookie中存储登录信息,比如用户名,id等等,在服务端响应数据到浏览器时,会自动把该cookie发送,浏览器接收到就会自动存到本地浏览器,之后每次浏览器发送请求,都会自动把该cookie携带到客户端,客户端发现存在该cookie,则表示该浏览器之前已经登录成功了。
api:
首先new一个cookie,key是cookie的名称,value是cookie对应的值
addCookie(),参数是上面自定义的cookie,通过addCookie把cookie添加到response响应对象,然后发送到客户端浏览器
发送后客户端浏览器就会自动保存,之后请求时会自动携带cookie,服务端request对象接收到数据,使用getCookies获取所有cookie,遍历cookie集合进行判断,使用getName和getValue获取键值对,如果key和value都对,则通过。
Cookie不支持移动端使用,且用户可以自己禁用cookie,不安全,不方便,且不能跨域
2.Session
session存储在服务端,相比于存储在客户端的cookie,更安全,但没有解决cookie的缺点,且集群服务器下不能直接使用session。
在浏览器第一次访问服务器时,服务器会把sessionID通过cookie响应给浏览器保存
格式为set-cookie : JSESSIONID=?
之后访问就会根据浏览器携带的JSESSION来判断
api:
首先会判断浏览器此次请求是否携带session,无,则服务端新创建一个session并响应给浏览器,有,则返回当前此次请求的session,
setAttribute()是存储session对象,参数定义session的名称和值
之后浏览器访问服务端,服务端通过请求对象getAttribute获取浏览器携带的session,查看session是否一样即可
3.JsonWebToken
支持任意端,服务端不保存令牌数据,但需要自己实现,登录成功后下发令牌,之后每次访问都要校验该令牌
JWT由三部分组成,第一部分是HEADER,记录令牌类型,签名算法,使用base-64编码
第二部分是payload有效载荷,携带自定义信息比如{ "id" : "1"},使用base-64编码
第三部分是signat签名,将第一部分和第二部分结合,再加入密钥得出的签名
生成方法:
先在pom文件引入jwt依赖
通过Jwts的bulider方法,先使用signWith定义签名算法,数字签名时需要的密钥
然后使用addClaims把自定义键值对数据加入第二部分,
然后使用setExpiration定义令牌过期时间
最后使用compact生成令牌,返回字符串
校验方法:
使用Jwts的解析方法parser获取setSignKey签名密钥,解析jwt令牌parseClaimsJws的字符串
最后getBody得到解析后的数据
二、filter过滤器
filt和servlet,listener是javaweb的三大组件,filter把请求拦截下来,然后执行一些特点的操作,比如登录处理,敏感字符处理
1.自定义filter
定义一个类,实现Filter接口,然后重写其中的init,destory,doFilter方法
init方法只会调用一次,destory是关闭服务器时,执行的方法,也只会执行一次,一般用于资源释放,清理工作
doFilter每次在请求资源时,都会执行该方法。
2.配置filter
在该类上添加注解@WebFilter(urlPatterns = ""),urlPatterns的值是要拦截请求的路径
3.在启动类上加注解@ServletComponentScan,因为filter是servlet的组件,不是springboot的
4.过滤器的执行流程:先拦截请求,然后执行一些通用的放行前逻辑,然后调用doFilter放行资源
放行后的资源在访问结束后,还会回到filter中,且执行放行后的逻辑代码
5.在一个web应用中可以定义多个过滤器,多个过滤器之间形成一条链
使用注解方式配置的过滤器,多个过滤器间的执行顺序是按过滤器名称的自然排序,比如Afilter和Bfilter,会先执行Afilter,然后执行doFilter方法放行到下个过滤器,然后执行Bfilter的放行前逻辑和doFilter方法,以此类推,直到过滤器执行完毕,此时放行的就是资源;请求完成后,回到filter中,然后执行Bfilter的放行后逻辑,执行Afliter的放行后逻辑,直到响应给浏览器。
三、拦截器interceptor
是spring框架提供,用来拦截controller方法执行,然后根据需要执行预先设置的代码
定义拦截器:
1.实现HandlerInterceptor接口,并且重写所有的方法,使用@Component将类转交给IOC容器
preHandle目标资源方法执行前执行,返回true表示放行,false代表不放行
postHandle目标资源方法执行后执行
afterCompletion视图渲染完毕后执行,是最后执行的方法
注册拦截器:
定义上面拦截器类的对象,通过@Autowired注解自动装配对象,然后定义一个拦截器方法,形参是InterceptorRegistry ,顾名思义,然后通过该形参对象执行addInterceptor方法,传入上面的拦截器对象,后面可以通过addPathPatterns定义拦截路径,也可以通过excludePathPatterns指定不需要拦截哪些资源
拦截路径有不同的形式,与过滤器不同的是,过滤器过滤所有是/*,而拦截器是/**,表明任意级路径下的资源都会被拦截,如果拦截器中定义/*,则表示只能拦截一级路径,二级以上路径的资源无法拦截
执行流程
过滤器和拦截器的区别:
实现的接口不同;过滤器拦截的是所有资源,而拦截器只会拦截spring环境中的资源,即控制器