以web系统的用户登录校验为例介绍会话技术与请求拦截技术
web网站后端开发中的一个常见需求就是登录校验和登录认证功能。
- 某些功能只有登录的用户才能使用。网站需要校验用户的登录信息。退出登录的用户需要重新登录。
- 未登录状态的用户触发某些事件时,网站会自动跳转到登录界面。
- 登录之后的跳转不需要重新登录。
单纯的校验登录信息比较简单,如果使用用户名及密码验证登录,可以编写简单的代码,查询数据库中保存的用户信息是否存在匹配的记录即可。问题并不在这里。
由于HTTP协议是无状态的协议,每次请求都是独立的,所以需要有一些方法对该用户是否已经登录进行判断。
直观的想法是用户登录之后可以产生一个登录标记,每次前端请求都首先获取该标记并判断该用户是否已经登录,由于该逻辑在处理每一个请求之前都需要进行,所以需要进行统一拦截。会话技术允许每次请求都可以获取到登录标记,而filter和intercepter允许我们进行统一拦截。
会话指的是用户通过浏览器访问web服务器的一次连接。用户开始访问服务器资源时,会话建立,而其中一方断开连接,会话结束。一次会话中可以包含多次请求和响应。会话跟踪维护浏览器的状态,服务器通过这个技术识别多次请求是否来自于同一浏览器(同一次会话),从而在同一次会话的多次请求之间共享数据,比如获取登录状态、验证码验证操作。
会话跟踪
下面记录的就是三种会话跟踪技术。
- cookie,客户端会话跟踪。
- session,服务端会话跟踪。
- 令牌。
cookie技术
cookie是客户端会话跟踪技术,服务端生成cookie的值之后响应给浏览器,浏览器将cookie存储在本地。接下来的请求中,浏览器会将本地的cookie携带在请求中一并发送给服务端。由于cookie是HTTP协议标准中支持的技术,因此各家浏览器实现都支持,而且cookie发送过程的自动进行的。cookie技术中双方交互是通过请求和响应头中关于cookie的字段进行的。在java web程序中可以通过http请求和响应对象设置和获取。
缺点在于:
- 移动端无法使用cookie技术。
- cookie存储在浏览器即客户端本地,数据不安全。
- 用户可以自己禁用cookie。
- cookie不能跨域。这个问题主要在前后端分离的程序中存在。
session技术
session是服务端会话跟踪技术,浏览器的请求可以从服务器获取会话对象session(第一次请求会创建该对象),服务端在响应对象中设置一个cookie为该session对象的id,因此可以说session技术是基于cookie技术的。java web程序中可以调用HttpSession
对象的方法对此进行操作。由于session对象存储在服务端,因此相对安全。
缺点在于:
- cookie的缺点也存在。
- 服务器在分布式集群环境中无法直接使用。
jwt令牌技术
这种技术是现在主要使用的技术。在登录请求时生成一个令牌,作为该用户的合法身份凭证,响应给前端,浏览器将其存储在本地。后面的每次请求都需要发送给服务端,服务端对令牌进行校验。这种方法可以支持PC和移动端,同时服务端不需要存储,解决了集群环境中的认证问题并减轻了服务端的存储负载。令牌技术的缺点在于需要开发者自行实现。
jwt全称json web token,用于通信双方以json格式安全地传输信息,可靠性依靠数字签名。jwt令牌最典型的应用场景就是登录认证。jwt令牌由三个部分组成:
- header,记录令牌类型、签名算法等。
- payload,有效载荷,携带信息,包括默认信息和自定义信息等。
- signature,数字签名。
这三个部分通过Base64进行编码,通过.
分隔。
Base64是一种编码方式,基于64个可打印的字符来表示二进制数据。
要使用jwt令牌,首先需要引入相关依赖。生成一个jwt令牌的基本流程包括:签名、设置自定义载荷、设置过期时间等等。具体的操作应该上网找一找模板代码即可。解析令牌也应该类似,需要指定签名密钥,主要是模板操作。如果令牌不合法(如已过期、被篡改、密钥不对等),解析就会抛出异常。
统一拦截请求
filter过滤器
filter是java web三大组件servlet、filter和listener之一,其中另外两个现在都很少使用了。filter可以把对资源的请求拦截下来,从而完成特殊的功能。filter一般用于完成一些通用的操作,如登录校验、统一编码处理、敏感字符处理等等。注意它并不是spring框架提供的。
filter程序的基本步骤包括:
-
定义filter类,实现
Filter
接口并重写方法。init
,web服务器启动创建filter时调用,只调用一次。doFilter
,每次拦截到请求时调用。拦截到请求之后可以根据业务逻辑进行判断:是否放行请求。destroy
,服务器关闭时调用,只调用一次。
-
配置,加上
@WebFilter
注解,配置拦截资源的路径。同时引导类上加上@ServletComponentScan
注解开启servlet组件支持。
filter拦截到请求之后以及请求处理完回到filter之后,都可以执行filter方法中编写的逻辑,即放行前和放行后。
注意,web应用中可以配置多个过滤器,依次相连形成过滤器链,最后一个过滤器放行后代码流会来到业务逻辑代码中。通过注解形式配置的filter,执行优先级是按照类名进行排序。
显然,登录校验中,对令牌的校验可以在filter的过滤方法中执行,如果校验通过,就将请求放行。
interceptor拦截器
interceptor是一种动态拦截方法调用的机制,是spring框架提供的,用来动态拦截controller方法的执行。功能与filter类似。自然,使用interceptor来实现登录校验的逻辑也与使用filter类似。
interceptor的基本步骤:
-
定义interceptor类,实现
HandlerInterceptor
接口,重写其方法。preHandle
,返回值为布尔值,在目标资源方法执行之前执行,返回true
说明放行,返回false
说明不放行。postHandle
,目标资源方法执行之后执行。afterCompletion
,视图渲染完之后才执行,是最后执行的。
-
注册配置该类。
- 编写一个
WebMvcConfigure
的实现类。 - 注入interceptor对象。
- 重写
addInterceptor
方法,对interceptor进行注册和配置。
- 编写一个
interceptor的拦截路径配置比较灵活,可以配置需要拦截哪些资源,以及不需要拦截哪些资源。具体的匹配规则如何编写,上网搜索一下就行,主要在于/*
和/**
的区别。
综合filter和interceptor来记录一下请求的处理流程。当filter和interceptor同时存在时,整体流程如下:
- 浏览器前端发起请求。
- web服务器的filter过滤请求。
- 来到spring框架提供的前端控制器
DispatcherServlet
。 - interceptor拦截请求。
- 最后由controller方法处理业务逻辑。
- 响应数据的流程是反过来的,即先来到interceptor,后来到filter,最后响应给前端。
注意,filter和interceptor的主要区别,除了接口不同,主要在于拦截的范围不同,前者拦截所有资源请求,而后者只会拦截spring环境中的资源请求。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇