登录校验,JWT令牌技术,过滤器(Filter)拦截器(interceptor)

登录功能:

前端传递json格式的数据。username(用户名)password(密码)。controller层对数据进行接收,由于是接收json格式的数据,所以我们把它封装到一个对象里面,由于登录是员工进行登录,所以我们封装到员工表中,public Result login(@RequestBody Emp emp){} 接收json格式的数据,我们使用@RequestBody注解,封装到对象中。看到返回类型,我们自定义了一个返回的实体类。LoginInfo

然后调用service层,进行业务处理。调用mapper层接口,把controller传递给service层的emp参数,传递给mapper层,

mapper层,根据参数对数据库进行查询,返回值类型是emp。如果查询到结果不为null,代表登录成功,查询结果为null,代表查询失败。

service层根据mapper层的返回结果进行判断,如果返回的emp不是null,则对返回出来的数据进行封装 return new LoginInfo(emp.getId,emp.getUserName,emp.getname,null),如果查询到没有数据,就返回null。

由于我们的service1层直接返回了 loginInfo,所以在返回给前端的时候还要进行判断,如果Logininfo不为null,返回Result.success(loginInfo)如果logininfo为null,return Result.error("用户名或密码错误");

引子:
  • 虽然我们写了 登录的接口,但是我们测试发现,就算在没有登录的情况下,用户还是可以随便对我们的系统进行访问。
  • 我们需要进行登录校验,如果用户登录,我们就下发jwt令牌,然后作为登录的标记,在每次用户请求的时候,都要携带这个jwt令牌,统一拦截器,会根据有没有令牌,进行校验。有就放行,没有就拦截。
  • 登录标记:用户登录之后,在后续的每一次请求中,都可以获取到该标记【会话技术】
  • 统一拦截:过滤器filter,拦截器interceptor

登录校验:

会话技术:

会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。

会话跟踪:

一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。

会话跟踪方案:
客户端会话跟踪技术:Cookie
优点:
  • HTTP协议中支持的技术
缺点:
  • 移动App无法使用Cookie
  • 不安全,用户可以自己禁用cookie
  • Cookie不能跨域
区分跨域的三个维度:
  • 协议,IP/域名,端口
服务端会话跟踪技术:Session
优点:
  • HTTP协议中支持的技术
缺点:
  • 移动端APP无法使用Cookie
  • 不安全,用户可以自己禁用Cookie
  • Cookie不能跨域

JWT令牌:

优点:
  • 支持PC端、移动端
  • 解决集群环境下的认证问题
  • 减轻服务器端存储压力
缺点:

需要自己实现

全称:
  • JSON Web Token (https://jwt.io/)
  • 定义了一种简洁的、自包含的格式,用于在通信双方以json数据格式安全的传输信息。
组成:
  • 第一部分:Header(头),记录令牌类型、签名算法等。 例如:{"alg":"HS256","type":"JWT"}
  • 第二部分:Payload(有效载荷),携带一些自定义信息、默认信息等。 例如:{"id":"1","username":"Tom"}
  • 第三部分:Signature(签名),防止Token被篡改、确保安全性。将header、payload融入,并加入指定秘钥,通过指定签名算法计算而来。
jwt依赖:
XML 复制代码
<dependency> 
     <groupId>io.jsonwebtoken</groupId>
     <artifactId>jjwt</artifactId> 
     <version>0.9.1</version>
</dependency>
生成令牌:

@Test public void testGenJwt() { Map<String, Object> claims = new HashMap<>(); claims.put("id", 10); claims.put("username", "itheima"); String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, "SVRIRUlNQQ==") .addClaims(claims) .setExpiration(new Date(System.currentTimeMillis() + 12*3600*1000)) .compact(); System.out.println(jwt);}

解析令牌:

@Testpublic void testParseJwt() { Claims claims = Jwts.parser().setSigningKey("SVRIRUlNQQ==") .parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAsInVzZXJuYW1lIjoiaXRoZWltYSIsImV4cCI6MTY5ODYyMjI1NX0.l6D1WG3...") .getBody(); System.out.println(claims);}

过滤器Filter:

快速入门:

概念:

Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。

过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。

过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

快速操作:

定义Filter:定义一个类,实现

@Slf4j //@WebFilter(urlPatterns = "/*") // 拦截所有请求

public class DemoFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

log.info("DemoFilter init 方法执行了... ");

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {

log.info("DemoFilter diFilter 方法执行了 放行前执行...");

chain.doFilter(servletRequest,servletResponse); //放行

log.info("DemoFilter diFilter 方法执行了 放行后执行...");

}

@Override

public void destroy() {

log.info("DemoFilter destory 方法执行了...");

}

}

配置Filter:Filter类上加@WebFilter注解,配置拦截路径。引导类上加@ServletComponentScan 开启Servlet组件支持。

@ServletComponentScan //开启spring boot对javaweb组件的支持(filter)

@SpringBootApplication

public class TilasRun {

public static void main(String[] args) {

SpringApplication.run(TilasRun.class, args);

}

}

详解:

放行后访问对应资源,资源访问完成后,还会回到Filter中吗?

会回到filter类中

如果回到Filter中,是重新执行还是执行放行后的逻辑呢?

会执行放行后的逻辑

拦截路径:

拦截具体路径:

/login 只有访问 /login 路径时,才会被拦截。

目录拦截:

/emps/* 只有访问/emps下的所有资源,才会被拦截。

拦截所有:

/* 访问所有资源,都会被拦截

过滤器链:

介绍:

一个web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。

顺序:

注解配置的Filter,优先级是按照过滤器类名(字符串)的自然排序。

登录校验-Filter:

所有的请求,拦截到了之后,都需要校验令牌吗?

有一个例外,登录请求不用拦截。

拦截到请求后,什么情况下才可以放行,执行操作业务?

有令牌,且令牌校验通过(合法);否则都返回未登录错误结果

步骤:

1,获取请求url。

2,判断请求url中是否包含login,如果包含,说明是登录操作,放行。

3,获取请求头中的令牌(token)。

4,判断令牌是否存在,如果不存在,响应401。

5,解析token,如果解析失败,响应401 。

6,放行。

拦截器Interceptor:

快速入门:

概念:

是一种动态拦截方法调用的机制,类似于过滤器。Spring框架中提供的,主要用来动态拦截控制器方法的执行。

作用:

拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

定义拦截器,实现HandlerInterceptor接口,并重写其所有方法。

注册拦截器

详解:

/* 一级路径 能匹配/depts,/emps,/login,不能匹配 /depts/1

/** 任意路径 能匹配/depts,/depts/1,/depts/1/2

/depts/* /depts下的下一级路径 能匹配/depts/1,不能匹配/depts/1/2,/depts

/depts/** /detps下的任意级路径 能匹配/depts,depts/1/2 不能匹配 emps/1

Filter和interceptot的区别:

接口规范不同:过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。

拦截范围不同:过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。

相关推荐
深圳蔓延科技7 小时前
Kafka的高性能之路
后端·kafka
Barcke7 小时前
深入浅出 Spring WebFlux:从核心原理到深度实战
后端
JuiceFS7 小时前
从 MLPerf Storage v2.0 看 AI 训练中的存储性能与扩展能力
运维·后端
大鸡腿同学7 小时前
Think with a farmer's mindset
后端
Moonbit7 小时前
用MoonBit开发一个C编译器
后端·编程语言·编译器
Reboot8 小时前
达梦数据库GROUP BY报错解决方法
后端
稻草人22228 小时前
java Excel 导出 ,如何实现八倍效率优化,以及代码分层,方法封装
后端·架构
渣哥8 小时前
原来 Java 里线程安全集合有这么多种
java
间彧8 小时前
Spring Boot集成Spring Security完整指南
java
掘金者阿豪8 小时前
打通KingbaseES与MyBatis:一篇详尽的Java数据持久化实践指南
前端·后端