登录认证-登录校验-Filter
目录
目录
什么是Filter?
什么是Servlet?
如果没有过滤器会怎样?
Filter快速入门
定义一个Filter:定义一个类,实现Filter接口,并实现所有方法
init初始化方法
doFilter拦截请求方法
destroy销毁方法
配置Filter:Filter类上加@WebFilter注解,配置拦截路径。引导类上加@ServletComponentScan开启Servlet组件支持。
如何放行?
令牌校验Filter
1.获取请求路径
.getRequestURI()获取请求路径
2.判断请求url中是否包含login
.contains判断是否包含路径
3.获取请求头中的token
.getHeader("token")获取请求头并指定请求头的名字token
4.判断令牌是否存在,如果不存在,响应 401
.isEmpty判断字符串是否为空串
.setStatus设置状态码
编辑5.解析token,如果解析失败,响应 401
Filter执行流程
问题1:
问题2
Filter-拦截路径
Filter-过滤器链
什么是Filter?
是Javaweb三大组件(Servlet,Filter,Listener)之一
什么是Servlet?
是运行在服务器端的一个小程序,基于Servlet可以开发动态的Web资源
过滤器可以把对资源的请求拦截下来
如果没有过滤器会怎样?
没有过滤器的前提下,我想校验这个员工是否登录了,我需要在每一个功能接口之前来做一个if条件判断,来校验这个员工是否登录了,如果登录了,我让它去访问对应的功能,如果没有登录,我就直接响应错误信息,我需要在每一个功能接口中都这么去做,那么这样操作的话就会非常繁琐
如果有了过滤器,我就可以把这部分通用的操作统一定义在过滤器中,在过滤器这个入口中进行统一的校验,如果校验不通过直接响应错误的结果,如果校验通过我再允许它去访问后端的这些资源,资源访问完毕后,它还会回到过滤器,最终给前端一个响应
所以通过过滤器就可以拦截前端发起的请求来完成一些通用的操作,比如我们的登录校验操作
Filter快速入门
定义一个Filter:定义一个类,实现Filter接口,并实现所有方法
init初始化方法
init方法会在Web程序启动时,在Filter实例化完毕之后,会自动调用,而且只会调用一次,在这个方法中,通常做一些准备环境的准备工作,
doFilter拦截请求方法
我们每一次拦截到前端发起的请求之后就会调用doFilter这个方法,所以doFilter这个方法会调用多次,每一次拦截之后都会调用doFilter
destroy销毁方法
它是在Web服务器关闭的时候调用的,只会调用一次,在这个方法中,通常做一些资源释放,环境清理的工作
配置Filter:Filter类上加@WebFilter注解,配置拦截路径。引导类上加@ServletComponentScan开启Servlet组件支持。
在定义的Filter这个类上加@WebFilter,然后声明urlPatterns属性,这个属性是用来指定当前过滤器是需要拦截哪些请求,配置一个/*是拦截所有请求
在SpringBoot中要想使用传统JavaWeb这些组件,需要在启动类上加上注解@ServletComponentScan来开启Servlet组件的支持
开启了对Sevlet组件的支持之后,它就会自动的扫描Servlet提供的这些注解,然后我们声明的这些组件就会生效了
打开APIfox发送请求,状态码为200但为什么没有响应数据?
因为我们刚才开发的doFilter,每一次发送请求都会被这个方法拦截,拦截后它就输出了一句日志,日志输出完毕后,也就结束了,它并没有放行让它去访问对应的资源
打开idea控制台,发现已拦截到了请求,每次拦截到请求都会调用doFilter这个方法
所以过滤器拦截到请求之后,要想让它去访问资源,需要放行
如何放行?
调用doFilter方法中的第三个形参,叫filterChain当中的doFilter方法,
这个里面需要传递两个参数,一个sercletRequest请求对象,一个servletResponse响应对象
这就是放行操作,有了这个操作之后,它就可以访问到对应的资源了
令牌校验Filter
1.获取请求路径
所有的请求参数都封装在了HTTPServletRequest这个对象中,
在调用doFilter时,servlettRequest和servletReponse的实际类型是HTTPRServleteQuest
所以先将ServletRequest对象强转成HTTPServletquest,因为它本身的类型就是HTTpServletquest
.getRequestURI()获取请求路径
完整的路径叫URL,URI指的是资源的访问路径,指的是不包含前面的协议,IP,和端口,指包含后面的这些路径,因为/employee/login直接拿到URI就可以了,拿到URL也没问题
2.判断请求url中是否包含login
.contains判断是否包含路径
如果是登录操作,放行
3.获取请求头中的token
.getHeader("token")获取请求头并指定请求头的名字token
4.判断令牌是否存在,如果不存在,响应 401
.isEmpty判断字符串是否为空串
如果.isEmpty的值为true,则该串为空串
.setStatus设置状态码
常量SC_UNAUTHORIZED代表的401状态码,就是未认证的意思,直接写401也可以
5.解析token,如果解析失败,响应 401
校验令牌可以调用一个工具类,在我们之前的工具类中,有parseToken()方法,里面可以传递token
Filter执行流程
问题1:
放行后访问对应资源,资源访问完成后,还会回到Filter中吗?
还会回到Filter中
问题2
如果回到FIlter中,是重新执行还是执行放行后的逻辑?
执行放行后的逻辑
Filter-拦截路径
FIlter可以根据需求,配置不同的拦截资源路径:
拦截路径 | urlPatterns值 | 含义 |
具体拦截路径 | /login | 只有访问/login路径时才会被拦截 |
目录拦截 | /emps/* | 访问/以emps开头的所有资源,都会被拦截 |
拦截所有 | /* | 访问所有资源,都会被拦截 |
/depts/** | /depts下的任意级路径 | 能匹配/depts,/depts/1,/depts/1/2,不能匹配/emps/1 |
Filter-过滤器链
一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链