一、登录校验
1.会话技术
1.1 会话
用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
1.2会话跟踪
一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
1.3实现方式
客户端技术:Cookie
服务端技术:Session
1.4 问题
① 服务端集群环境下Session的共享问题。
② 移动端APP端无法使用Cookie
1.5 令牌技术优势:
① 解决了集群环境下的认证问题,减轻服务器端的存储压力
② 支持PC端、移动端
2.JWT令牌
2.1概念
JSON Web Token(JWT)是一个开放的行业标准(RFC 7519),它定义了一种简洁的、自包含的协议格式,用于在通信双方传递json对象,传递的信息经过数字签名可以被验证和信任。
2.2组成
第一部分:Header(头), 作用:记录令牌类型、签名算法等。
例如{"alg":"HS256","typ”:””JWT”}
第二部分:Payload(有效载荷),作用:携带一些用户信息及过期时间等。
例如:{“id":"1","username":“Tom"}
第三部分:Signature(签名),作用:防止Token被篡改、确保安全性。
例如:计算出来的签名,一个字符串
2.3Jwt令牌的生成及校验
① 先导入依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
② 生成JWT令牌
@Test
public void testCreateJWT(){
Map<String, Object> claims=new HashMap<>();
claims.put("signWith","setClaims");
claims.put("setExpiration","compact");
claims.put("compact","compact");
claims.put("setClaims","setClaims");
String jwt = Jwts.builder()
.signWith(SignatureAlgorithm.HS256, "itheima")
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))
.compact();
System.out.println("jwt = " + jwt);
}
③ 解析JWT令牌
@Test
public void ParserJWT() {
Map<String, Object> claims = Jwts.parser()
.setSigningKey("itheima")
.parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJzZXRDbGFpbXMiOiJzZXRDbGF" +
"pbXMiLCJjb21wYWN0IjoiY29tcGFjdCIsInNldEV4cGlyYXRpb24iOiJjb21wY" +
"WN0Iiwic2lnbldpdGgiOiJzZXRDbGFpbXMiLCJleHAiOjE2OTEyNDA2MzJ9.dHJPd" +
"2VjxqxgyqCtrR1BSdTdpIc_TZJ7S6kuRs43UWM")
.getBody();
System.out.println(claims.get("signWith"));
System.out.println(claims.get("compact"));
System.out.println(claims.get("setExpiration"));
System.out.println(claims.get("setClaims"));
}
3.过滤器— filter
3.1 概念
— Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
— 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
— 过滤器一般完成一些通用的操作,比如:登陆鉴权、统一编码处理、敏感字符处理等等…
3.2 快速入门
— 定义类,实现 Filter接口,并重写doFilter
方法
— 在类上定义 @WebFilter 注解,配置Filter拦截资源的路径。
— 在 doFilter 方法中输出一句话,并放行。
— 在引导类上只用 @ServletComponentScan 开启Servlet组件支持。
@WebFilter(urlPatterns = "/*")
public class Filter2 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("filer2拦截执行了");
HttpServletRequest request = (HttpServletRequest) servletRequest;
String url = request.getRequestURL().toString();
if (url.contains("login")) {
filterChain.doFilter(servletRequest,servletResponse);
}
String jwt = request.getHeader("token");
if (jwt == null) {
extracted(servletResponse);
return;
}
try {
Claims claims = JwtUtils.parseJWT(
jwt);
filterChain.doFilter(servletRequest,servletResponse);
} catch (Exception e) {
e.printStackTrace();
extracted(servletResponse);
}
}
private void extracted(ServletResponse servletResponse) throws IOException {
Result errorResult = Result.error("not_LOGIN");
ObjectMapper objectMapper =new ObjectMapper();
String json = objectMapper.writeValueAsString(errorResult);
servletResponse.getWriter().write(json);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
3.3 Filter执行流程
3.3.1 流程
浏览器请求—>放行逻辑前—>放行—>web资源访问—>放行后逻辑—>相应浏览器
3.3.2 问题
— 放行后访问对应资源,资源访问完成后,还会回到Filter中吗?
会
— 如果回到Filter中,是重新执行还是执行放行后的逻辑呢?
执行放行后逻辑
3.4 Filter拦截路径配置
3.5 登录校验Filter-流程
① 获取请求路径
② 判断请求url中是否包含login,如果包含,说明是登录操作,放行
③ 获取请求头中的令牌(token)
④ 判断令牌是否存在,如果不存在,返回错误结果(未登录)
⑤ 解析token,如果解析失败,返回错误结果(未登录)
⑥ 放行
4.拦截器 Interceptor
4.1 概念
是一种动态拦截方法调用的机制,类似于过滤器。在SpringMVC中动态拦截控制器方法的执行。
4.2 作用
在指定的方法调用前后执行预先设定的代码,完成功能增强。
4.3 快速入门
— 定义拦截器,实现HandlerInterceptor接口,并重写其所有方法(preHandle,postHandle,afterComplecation)。
— 注册拦截器(实现WebMvcConfigurer ,配置注解@Configuration,重写addInterceptors方法)
4.4 执行流程
请求—> doFilter—> DispatcherServlet—> reHandle —>Controller中的方法执行—> postHandle—> afterComplecation—> doFilter
4.5 登录校验
同Filter校验过程
4.6Interceptor和Filter的区别
① 接口规范不同
过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
② 拦截范围不同
过滤器Filter会拦截所有的资源,而Interceptor只会拦截Spring环境中的资源。
二、异常处理
1.概念
— 程序开发过程中不可避免的会遇到异常现象
— 出现异常
2.异常处理
2.1 try-catch
在Controller的方法中进行try…catch处理
2.2 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler3 {
@ExceptionHandler
public Result ex(Exception ex) {
ex.printStackTrace();
return Result.error("系统繁忙,请稍后再试");
}
}
出现
异常时,默认返回的结果不符合规范 出现异常时,默认返回的结果不符合规范出现异常时,默认返回的结果不符合规范 出现异常时,默认返回的结果不符合规范
出现异 常时,默认返回的结果不符合规范