登录验证,JWT,过滤器,拦截器使用总结 2023

发布时间 2023-06-24 00:20:28作者: 大树2

登录验证,JWT,过滤器,拦截器使用总结

1.cookie
浏览器禁用后不可用,跨域不可用

2.session
集群不可用,

3.JWT
3.1 添加依赖
jwt.io

  <!--JWT令牌-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>

3.2 JwtUtils

package com.itheima.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;

public class JwtUtils {

private static String signKey = "itheima";
private static Long expire = 43200000L;

/**
 * 生成JWT令牌
 * @param claims JWT第二部分负载 payload 中存储的内容
 * @return
 */
public static String generateJwt(Map<String, Object> claims){
    String jwt = Jwts.builder()
            .addClaims(claims)
            .signWith(SignatureAlgorithm.HS256, signKey)
            .setExpiration(new Date(System.currentTimeMillis() + expire))
            .compact();
    return jwt;
}

/**
 * 解析JWT令牌
 * @param jwt JWT令牌
 * @return JWT第二部分负载 payload 中存储的内容
 */
public static Claims parseJWT(String jwt){
    Claims claims = Jwts.parser()
            .setSigningKey(signKey)
            .parseClaimsJws(jwt)
            .getBody();
    return claims;
}

}

3.filter 过滤器:登录验证,敏感次,

3.1开启了对filter servlet组件的支持
@ServletComponentScan //开启了对servlet组件的支持
@SpringBootApplication
public class TliasWebManagementApplication {

public static void main(String[] args) {
    SpringApplication.run(TliasWebManagementApplication.class, args);
}

}

3.2 DemoFilter

package com.itheima.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 {
System.out.println("init 初始化方法执行了");
}

@Override //拦截到请求之后调用, 调用多次
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    System.out.println("Demo 拦截到了请求...放行前逻辑");
    //放行
    chain.doFilter(request,response);

    System.out.println("Demo 拦截到了请求...放行后逻辑");
}

@Override //销毁方法, 只调用一次
public void destroy() {
    System.out.println("destroy 销毁方法执行了");
}

}

3.3 过滤器链:
按过滤器类的名词优先执行

3.4 登录过滤器
package com.itheima.filter;

import com.alibaba.fastjson.JSONObject;
import com.itheima.pojo.Result;
import com.itheima.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
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 request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;

    //1.获取请求url。
    String url = req.getRequestURL().toString();
    log.info("请求的url: {}",url);

    //2.判断请求url中是否包含login,如果包含,说明是登录操作,放行。
    if(url.contains("login")){
        log.info("登录操作, 放行...");
        chain.doFilter(request,response);
        return;
    }

    //3.获取请求头中的令牌(token)。
    String jwt = req.getHeader("token");

    //4.判断令牌是否存在,如果不存在,返回错误结果(未登录)。
    if(!StringUtils.hasLength(jwt)){
        log.info("请求头token为空,返回未登录的信息");
        Result error = Result.error("NOT_LOGIN");
        //手动转换 对象--json --------> 阿里巴巴fastJSON
        String notLogin = JSONObject.toJSONString(error);
        resp.getWriter().write(notLogin);
        return;
    }

    //5.解析token,如果解析失败,返回错误结果(未登录)。
    try {
        JwtUtils.parseJWT(jwt);
    } catch (Exception e) {//jwt解析失败
        e.printStackTrace();
        log.info("解析令牌失败, 返回未登录错误信息");
        Result error = Result.error("NOT_LOGIN");
        //手动转换 对象--json --------> 阿里巴巴fastJSON
        String notLogin = JSONObject.toJSONString(error);
        resp.getWriter().write(notLogin);
        return;
    }

    //6.放行。
    log.info("令牌合法, 放行");
    chain.doFilter(request, response);

}

}

3.5 拦截器:interceptor 拦截请求

浏览器--》Filter--》DispatcherServlet--->Interceptor--->controller

过滤器:需实现Filter接口;而拦截器需实现HandlerInterceptor接口
过滤器:会过滤所有资源;而拦截器Interceptor只会拦截spring环境中的资源;

/**
/*
/deps/*
/deps/**

备注:
过滤器和拦截器在实践开发中使用一种就可以。