以web系统的用户登录校验为例介绍会话技术与请求拦截技术

web网站后端开发中的一个常见需求就是登录校验和登录认证功能。

  1. 某些功能只有登录的用户才能使用。网站需要校验用户的登录信息。退出登录的用户需要重新登录。
  2. 未登录状态的用户触发某些事件时,网站会自动跳转到登录界面。
  3. 登录之后的跳转不需要重新登录。

单纯的校验登录信息比较简单,如果使用用户名及密码验证登录,可以编写简单的代码,查询数据库中保存的用户信息是否存在匹配的记录即可。问题并不在这里。

由于HTTP协议是无状态的协议,每次请求都是独立的,所以需要有一些方法对该用户是否已经登录进行判断。

直观的想法是用户登录之后可以产生一个登录标记,每次前端请求都首先获取该标记并判断该用户是否已经登录,由于该逻辑在处理每一个请求之前都需要进行,所以需要进行统一拦截会话技术允许每次请求都可以获取到登录标记,而filter和intercepter允许我们进行统一拦截。

会话指的是用户通过浏览器访问web服务器的一次连接。用户开始访问服务器资源时,会话建立,而其中一方断开连接,会话结束。一次会话中可以包含多次请求和响应会话跟踪维护浏览器的状态,服务器通过这个技术识别多次请求是否来自于同一浏览器(同一次会话),从而在同一次会话的多次请求之间共享数据,比如获取登录状态、验证码验证操作。

会话跟踪

下面记录的就是三种会话跟踪技术。

  1. cookie,客户端会话跟踪。
  2. session,服务端会话跟踪。
  3. 令牌。

cookie技术

cookie是客户端会话跟踪技术,服务端生成cookie的值之后响应给浏览器,浏览器将cookie存储在本地。接下来的请求中,浏览器会将本地的cookie携带在请求中一并发送给服务端。由于cookie是HTTP协议标准中支持的技术,因此各家浏览器实现都支持,而且cookie发送过程的自动进行的。cookie技术中双方交互是通过请求和响应头中关于cookie的字段进行的。在java web程序中可以通过http请求和响应对象设置和获取。

缺点在于:

  1. 移动端无法使用cookie技术。
  2. cookie存储在浏览器即客户端本地,数据不安全。
  3. 用户可以自己禁用cookie。
  4. cookie不能跨域。这个问题主要在前后端分离的程序中存在。

session技术

session是服务端会话跟踪技术,浏览器的请求可以从服务器获取会话对象session(第一次请求会创建该对象),服务端在响应对象中设置一个cookie为该session对象的id,因此可以说session技术是基于cookie技术的。java web程序中可以调用HttpSession对象的方法对此进行操作。由于session对象存储在服务端,因此相对安全。

缺点在于:

  1. cookie的缺点也存在。
  2. 服务器在分布式集群环境中无法直接使用。

jwt令牌技术

这种技术是现在主要使用的技术。在登录请求时生成一个令牌,作为该用户的合法身份凭证,响应给前端,浏览器将其存储在本地。后面的每次请求都需要发送给服务端,服务端对令牌进行校验。这种方法可以支持PC和移动端,同时服务端不需要存储,解决了集群环境中的认证问题并减轻了服务端的存储负载。令牌技术的缺点在于需要开发者自行实现。

jwt全称json web token,用于通信双方以json格式安全地传输信息,可靠性依靠数字签名。jwt令牌最典型的应用场景就是登录认证。jwt令牌由三个部分组成:

  1. header,记录令牌类型、签名算法等。
  2. payload,有效载荷,携带信息,包括默认信息和自定义信息等。
  3. signature,数字签名。

这三个部分通过Base64进行编码,通过.分隔。

Base64是一种编码方式,基于64个可打印的字符来表示二进制数据。

要使用jwt令牌,首先需要引入相关依赖。生成一个jwt令牌的基本流程包括:签名、设置自定义载荷、设置过期时间等等。具体的操作应该上网找一找模板代码即可。解析令牌也应该类似,需要指定签名密钥,主要是模板操作。如果令牌不合法(如已过期、被篡改、密钥不对等),解析就会抛出异常。

统一拦截请求

filter过滤器

filter是java web三大组件servlet、filter和listener之一,其中另外两个现在都很少使用了。filter可以把对资源的请求拦截下来,从而完成特殊的功能。filter一般用于完成一些通用的操作,如登录校验、统一编码处理、敏感字符处理等等。注意它并不是spring框架提供的。

filter程序的基本步骤包括:

  1. 定义filter类,实现Filter接口并重写方法。

    • init,web服务器启动创建filter时调用,只调用一次。
    • doFilter,每次拦截到请求时调用。拦截到请求之后可以根据业务逻辑进行判断:是否放行请求。
    • destroy,服务器关闭时调用,只调用一次。
  2. 配置,加上@WebFilter注解,配置拦截资源的路径。同时引导类上加上@ServletComponentScan注解开启servlet组件支持。

filter拦截到请求之后以及请求处理完回到filter之后,都可以执行filter方法中编写的逻辑,即放行前放行后

注意,web应用中可以配置多个过滤器,依次相连形成过滤器链,最后一个过滤器放行后代码流会来到业务逻辑代码中。通过注解形式配置的filter,执行优先级是按照类名进行排序。

显然,登录校验中,对令牌的校验可以在filter的过滤方法中执行,如果校验通过,就将请求放行。

interceptor拦截器

interceptor是一种动态拦截方法调用的机制,是spring框架提供的,用来动态拦截controller方法的执行。功能与filter类似。自然,使用interceptor来实现登录校验的逻辑也与使用filter类似。

interceptor的基本步骤:

  1. 定义interceptor类,实现HandlerInterceptor接口,重写其方法。

    • preHandle,返回值为布尔值,在目标资源方法执行之前执行,返回true说明放行,返回false说明不放行。
    • postHandle,目标资源方法执行之后执行。
    • afterCompletion,视图渲染完之后才执行,是最后执行的。
  2. 注册配置该类。

    • 编写一个WebMvcConfigure的实现类。
    • 注入interceptor对象。
    • 重写addInterceptor方法,对interceptor进行注册和配置。

interceptor的拦截路径配置比较灵活,可以配置需要拦截哪些资源,以及不需要拦截哪些资源。具体的匹配规则如何编写,上网搜索一下就行,主要在于/*/**的区别。

综合filter和interceptor来记录一下请求的处理流程。当filter和interceptor同时存在时,整体流程如下:

  1. 浏览器前端发起请求。
  2. web服务器的filter过滤请求。
  3. 来到spring框架提供的前端控制器DispatcherServlet
  4. interceptor拦截请求。
  5. 最后由controller方法处理业务逻辑。
  6. 响应数据的流程是反过来的,即先来到interceptor,后来到filter,最后响应给前端。

注意,filter和interceptor的主要区别,除了接口不同,主要在于拦截的范围不同,前者拦截所有资源请求,而后者只会拦截spring环境中的资源请求。

posted @   随机生成一个id  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 2分钟学会 DeepSeek API,竟然比官方更好用!
· .NET 使用 DeepSeek R1 开发智能 AI 客户端
· 10亿数据,如何做迁移?
· 推荐几款开源且免费的 .NET MAUI 组件库
· c# 半导体/led行业 晶圆片WaferMap实现 map图实现入门篇
点击右上角即可分享
微信分享提示