一,简介
保证数据安全,用户在访问网站里面的页面时,需要进行登录校验(会话跟踪)
相关技术有cookie和session,后者基于前者,但是有些弊端,比如cookies在移动端无效,无法跨域等问题,因此现在的主流技术是Jwt令牌技术,
jwt,定义一种简洁,自包含的格式,用于通信双方以Json数据格式安全的传输信息,由于签名存在,这些信息时可靠的
下图为jwt相关格式和含义

1.1,原理
由于Http协议访问是没有状态的,第一次访问和第二次访问互不影响,因此员工在对服务器进行操作的时候,服务器无法判断员工是否登录。 jwt令牌技术是用户在登录页面是,会对用户输入的用户名进行判断,如果存在就会下发令牌,可以进行后续页面操作,令牌也有一定时间,后端响应前端请求时,会携带jwt,前端接受并且保存在浏览器本地,前端进行查询等操作会把jwt保存在方法头中,用作查询凭证。后端会通过Jwt验证前端的每次请求,通过Filter和intercepoter技术进行校验。
1.2,相关代码
public class JwtUtils {
private static String signingKey = "itheima";
private static Long expire = 43200000L;
public static String generateJwt(Map<String,Object> claims){
String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, signingKey)//签名算法
.setClaims(claims)//设置自定义内容
.setExpiration(new Date(System.currentTimeMillis() + expire))//设置生效时间,从现在往后退一个小时
.compact();//
return jwt;
}
public static Claims ParseJwt(String jwt){
Claims claims = Jwts.parser()
.setSigningKey(signingKey)//和前面的令牌一样,
.parseClaimsJws(jwt)
.getBody();//生成返回值
return claims;
}
}
二,Filter(过滤器)

2.1快速入门
1.实现Filter接口,主要实现doFilter方法
2.配置@WebFilter(urlpatterns="/*") @ServletComponetScan(Filter不是springboot的组件,时servlet的)
实现代码
package com.example.tiaswebmanagement.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(urlPatterns = "/*")//配置过滤器,拦截所有请求
public class DemoFilter implements Filter {
@Override//初始化,只调用一次
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
System.out.println("初始化执行了");
}
@Override//过滤方法,每个请求都会调用,
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
// System.out.println("拦截请求");
filterChain.doFilter(servletRequest,servletResponse);
}
@Override//销毁方法,只调用一次
public void destroy() {
// Filter.super.destroy();
System.out.println("销毁方法执行了");
}
}
2.2.过滤器链
一个web应用中,可以配置多个过滤器

先执行了ABCfilter过滤器,再执行DemoFilter,这个是按照首字母排序决定执行顺序

执行流程:请求--放行前逻辑--放行--资源--放行后逻辑
拦截路径:/login
/depts/*
2.3.登录校验流程

package com.example.tiaswebmanagement.filter;
import com.alibaba.fastjson.JSONObject;
import com.example.tiaswebmanagement.pojo.Result;
import com.example.tiaswebmanagement.utils.JwtUtils;
import com.github.pagehelper.util.StringUtil;
import io.jsonwebtoken.Jwt;
import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject;
import org.springframework.util.StringUtils;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//1.获取url
HttpServletRequest req=(HttpServletRequest) servletRequest;//用HttpServletRequest获取请求头
HttpServletResponse resp=(HttpServletResponse) servletResponse;
String url = req.getRequestURI().toString();
log.info("请求的url{}",url);
//2.判断请求中是否包含login,包含则放行
if (url.contains("login")){
log.info("登录操作 放行。。。。。");
filterChain.doFilter(servletRequest,servletResponse);//放行
return;//让代码不再继续向下执行
}
//3.判断请求头中是否携带token令牌,如果携带则放行,否则拦截
String jwt = req.getHeader("token");
//4.判断是否为空,为空拦截,不为空则放行
if (!StringUtils.hasLength(jwt)){
log.info("请求头token 为空,返回未登录信息");
Result error = Result.error("NOT_LOGIN");//响应未登录信息
String s = JSONObject.toJSONString(error);//转化成Json类型数据,需要在Pom中加入依赖
resp.getWriter().write(s);//获取输出流,响应给浏览器
return;
}//5,解析token,如果失败就返回错误信息,如果成功就放行
try {
JwtUtils.ParseJwt(jwt);
} catch (Exception e) {//解析失败
e.printStackTrace();
log.info("解析令牌失败,返回未登录信息");
Result error = Result.error("NOT_LOGIN");//响应未登录信息
String s = JSONObject.toJSONString(error);//转化成Json类型数据,需要在Pom中加入依赖
resp.getWriter().write(s);//获取输出流,响应给浏览器
return;
}
//6.放行
log.info("令牌合法,放行");
filterChain.doFilter(servletRequest,servletResponse);
}
}
三,拦截器Interceptor
3.1.概念
是一种拦截方法用的机制,类似过滤器,Spring框架提供,作用:拦截请求,在指定方法调用后,根据业务预先设定的代码
3.2.快速入门
(1),定义拦截器,实现HandlerInterceptor接口,重写所有方法
(2),注册拦截器

package com.example.tiaswebmanagement.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override//在请求处理之前调用,只有返回true才会继续向下执行,false取消当前请求
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle运行");
return false;
}
@Override//在请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle运行");
}
@Override//在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion运行");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
//
注册拦截器
package com.example.tiaswebmanagement.config;
//注册拦截器
import com.example.tiaswebmanagement.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration//配置类
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginCheckInterceptor loginCheckInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginCheckInterceptor).addPathPatterns("/**");//添加拦截器,拦截所有资源;.excludePathPatterns()不需要拦截的资源
}
}
拦截器拦截路径

拦截器执行流程

3.3,两者区别
接口规范不同,过滤器通过Filter实现接口,拦截器通过HandlerInterceptor接口
拦截范围不同:过滤器会拦截所有资源,而后者只能拦截Spring环境中的资源
1085

被折叠的 条评论
为什么被折叠?



