JWT两种拦截方式
filter(过滤器)和interceptor(拦截器)的区别filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制。filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;filter的过滤范围比interceptor大,filter除了过滤请求外通过通
·
filter(过滤器)和interceptor(拦截器)的区别
- filter基于filter接口中的doFilter回调函数,interceptor则基于Java本身的反射机制。
- filter是依赖于servlet容器的,没有servlet容器就无法回调doFilter方法,而interceptor与servlet无关;
- filter的过滤范围比interceptor大,filter除了过滤请求外通过通配符可以保护页面、图片、文件等,而interceptor只能过滤请求,只对action起作用,在action之前开始,在action完成后结束。
- filter的过滤一般在加载的时候在init方法声明,而interceptor可以通过在xml声明是guest请求还是user请求来辨别是否过滤;
- interceptor可以访问action上下文、值栈里的对象,而filter不能;
- 在action的生命周期中,拦截器可以被多次调用,而过滤器只能在容器初始化时被调用一次。
具体实现:
一、Filter:过滤器
启动类需要添加:
@ServletComponentScan(basePackages = “filter路径”)
import com.auth0.jwt.interfaces.Claim;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@WebFilter(filterName = "JwtFilter", urlPatterns = {"/**"})
/**
* 过滤器,过滤token信息
* @author lcr
*/
public class JwtFilter implements Filter {
// 设置的不需要过滤的url
@Value("${filter.config.excludeUrls}")
private String excludeUrls;
@Override
/**
* 初始方法
*/
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
/**
* 过滤请求
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
// 设置响应编码为UTF-8
response.setCharacterEncoding("UTF-8");
//获取请求uri
String url = request.getRequestURI();
// 判断请求uri是否需要过滤(方法在下面)
if (excludeUrls.indexOf(url) != -1) {
// 不需要,放行
chain.doFilter(request, response);
return;
}
//获取 header里的token
String token = request.getHeader("sign");
// 跨域请求options 返回为空
String str = "OPTIONS";
if (str.equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
// 除了options跨域请求,都进入到jwt校验
else {
if (token == null) {
response.getWriter().write("没有token!");
return;
}
// 校验接口传进来的token信息
Map<String, Claim> userData = JwtUtil.verifyToken(token);
if (userData == null) {
response.getWriter().write("签名验签失败 !");
return;
}
// 验证请求放行
chain.doFilter(request, response);
}
}
}
二、拦截器
configuration: 拦截器配置
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
/**
* @author lcr
* @title: JwtInterceptorConfig
* @projectName practice_demo
* @description: 拦截器配置
* @date 2021/9/9 14:36
*/
@Configuration
public class JwtInterceptorConfig extends WebMvcConfigurationSupport {
@Resource
private JwtInterceptor jwtInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器,要声明拦截器对象和要拦截的请求
registry.addInterceptor(jwtInterceptor)
//所有路径都被拦截
.addPathPatterns("/**")
// 获取token信息
.excludePathPatterns("/getToken");
}
}
interceptor:拦截器
import com.auth0.jwt.interfaces.Claim;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* @author lcr
* @title: JwtInterceptor
* @projectName practice_demo
* @description: jwt拦截器
* @date 2021/9/9 14:30
*/
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 设置响应编码为UTF-8
response.setCharacterEncoding("UTF-8");
//获取 header里的token
String token = request.getHeader("sign");
// 跨域请求options 返回为空
String str = "OPTIONS";
if (str.equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return false;
}// 除了options跨域请求,都进入到jwt校验
else {
if (token == null) {
response.getWriter().write("没有token!");
return false;
}
// 校验接口传进来的token信息
Map<String, Claim> userData = JwtUtil.verifyToken(token);
if (userData == null) {
response.getWriter().write("签名验签失败 !");
return false;
}
return true;
}
}
}
工具类
JwtUtils: jwt生成token、验签类。
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* JWT工具类
*
* @author lcr
*/
public class JwtUtil {
/**
* 日志
*/
private static final Logger logger = LoggerFactory.getLogger(JwtUtil.class);
/**
* 密钥
*/
private static final String SECRET = "my_secret";
/**
* 过期时间 单位为秒
**/
private static final long EXPIRATION = 1800L;
/**
* 生成用户token,设置token超时时间
*/
public static String createToken() {
//过期时间
Date expireDate = new Date(System.currentTimeMillis() + EXPIRATION * 1000);
// 存放head值
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");
// 加密方式 header payload采用的BASE64加密方式(对称加密) secret采用HMAC(哈希加密)
String token = JWT.create()
// 添加头部
.withHeader(map)
//可以将基本信息放到claims中
// 添加载荷PAYLOAD
// 用户编号
.withClaim("id", "0001")
// 用户名称
.withClaim("userName", "lcr")
// 超时设置,设置过期的日期
.withExpiresAt(expireDate)
// 签发时间
.withIssuedAt(new Date())
// sign签名 SECRET加密 采用散列加密
.sign(Algorithm.HMAC256(SECRET));
return token;
}
/**
* 校验token并解析token
*/
public static Map<String, Claim> verifyToken(String token) {
DecodedJWT jwt = null;
try {
// 校验header payload signature是否合法 校验过期时间
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
jwt = verifier.verify(token);
} catch (Exception e) {
logger.error(e.getMessage());
logger.error(" 签名验签失败 !");
//解码异常则抛出异常
return null;
}
return jwt.getClaims();
}
}
更多推荐
已为社区贡献1条内容
所有评论(0)