spring boot拦截器代码实现

目录

 

一、需求

二、代码实现

三、拦截器运行流程


一、需求

为了防止刷接口行为,我们要加上访问功能接口时需要登录并且限制登录时长的拦截器

二、代码实现

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qt.intelliteach5g.controller.sso.RequestSsoController;
import com.qt.intelliteach5g.util.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import redis.clients.jedis.JedisCluster;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;


@Configuration
public class AdminInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    RedisService redisService;
    private long timestampRang=600;//单位秒
    public final static String ADMIN_LOGIN_TOKEN_PREFIX = "manager:";
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        //时间戳判定,防止重放攻击
        String timestamp = InterceptorUtil.getTimestampFromRequest(request);
        if (timestamp==null||timestamp.isEmpty()) {
            InterceptorUtil.responseResult(response,"请加入时间戳",-1);
            return false;
        }
        long requestTimestamp = Long.valueOf(timestamp);
        long nowTimestamp=new Date().getTime();
        if (Math.abs(nowTimestamp-requestTimestamp)>timestampRang*1000) {
            InterceptorUtil.responseResult(response,"请求时间戳与后台时间戳相差超过10分钟,拒绝访问",-1);
            return false;
        }
        //token鉴定
        String tokenKey=  ADMIN_LOGIN_TOKEN_PREFIX+InterceptorUtil.getTokenFromRequest(request);
        String resultString = (String) redisService.get(tokenKey);
        if (resultString==null) {
            InterceptorUtil.responseResult(response,"token无效",-999);
            return false;
        }else {
            redisService.set(resultString, 1800);
            request.setAttribute("loginUserId",this.getUserIdFromRequest(resultString));

        }
        /鉴权
        //获取当前用户拥有的权限
//        long loginUserId = (long) request.getAttribute("loginUserId");
//        List<Integer> userHavePermissionList = menuDao.queryByAdminUserId(loginUserId);
//        //获取当前请求地址需要的权限
//        List<Integer> requestNeedPermissionList = this.getRequestNeedPermissionList((HandlerMethod) o);
//        //鉴权比较
//        if (!userHavePermissionList.containsAll(requestNeedPermissionList)) {
//            InterceptorUtil.responseResult(response,"无权限操作该接口",-998);
//            return false;
//        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

    public String getUserIdFromRequest(String resultString) {
        JSONObject jsonObject = JSON.parseObject(resultString);
        String content = jsonObject.getString("content");
        return JSON.parseObject(content).getString("id");
    }

//    public List<Integer> getRequestNeedPermissionList(HandlerMethod handlerMethod) {
//        List<Integer> needPermissionList = new ArrayList<>();
//        NeedPermissionIdArray needPermissionIdArrayAnnotation = handlerMethod.getMethod().getAnnotation(NeedPermissionIdArray.class);
//        if (needPermissionIdArrayAnnotation!=null) {
//            int[] value = needPermissionIdArrayAnnotation.value();
//            for (int i : value) {
//                needPermissionList.add(i);
//            }
//        }
//        return needPermissionList;
//    }


}

2)在springboot中,指定interceptor:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class MyInterceptorConfig implements WebMvcConfigurer {
    @Autowired
    private AdminInterceptor interceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        System.out.println("执行了拦截器");
        registry.addInterceptor(interceptor)
                //添加需要验证登录用户操作权限的请求
                .addPathPatterns("/manger/**")
                //排除不需要验证登录用户操作权限的请求
                .excludePathPatterns("/user/**");


}

3)interceptor的时间戳和token的HTTP工具类

import com.qt.intelliteach5g.util.JSONUtil;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;


public class InterceptorUtil {
    public static String getTokenFromRequest(HttpServletRequest request) {
        String token=null;
        token = request.getHeader("token");
        if (token == null || token.isEmpty()) {
            token = request.getParameter("token");
        }
//        if (token == null || token.isEmpty()) {
//            Cookie[] cookies = request.getCookies();
//            for (Cookie cookie : cookies) {
//                if (cookie.getName().equals("token")) {
//                    token=cookie.getName();
//                }
//            }
//        }
        return token;
    }
    public static String getTimestampFromRequest(HttpServletRequest request) {
        String token=null;
        token = request.getHeader("timestamp");
        if (token == null || token.isEmpty()) {
            token = request.getParameter("timestamp");
        }
//        if (token == null || token.isEmpty()) {
//            Cookie[] cookies = request.getCookies();
//            for (Cookie cookie : cookies) {
//                if (cookie.getName().equals("timestamp")) {
//                    token=cookie.getName();
//                }
//            }
//        }
        return token;
    }






    public static void responseResult(HttpServletResponse httpServletResponse, String message, int code) throws IOException {
        httpServletResponse.setContentType("text/html; charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write(JSONUtil.toErrorJson(code,message));
        writer.flush();
        writer.close();
    }

    public static String getRobotIdFromRequest(HttpServletRequest request) {
        return request.getHeader("robotId");
    }

    public static String getRequestBody(HttpServletRequest request) {
        String body= null;
        try {
            BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8"));
            StringBuilder responseStrBuilder = new StringBuilder();
            String inputStr;
            while ((inputStr = streamReader.readLine()) != null)
                responseStrBuilder.append(inputStr);
            body=responseStrBuilder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return body;
    }

}

三、拦截器运行流程

1)首先需要登录获取token和当前的时间时间戳

2)访问接口的时候需要加上从登录上那获取到的token和时间戳作为参数传过去,这样才能有效的访问功能。

接口例子:http://localhost:8080/manger/permission/getAllPermissions?timestamp=1586307386000&token=3cb58179-9a6a-43e8-98b2-2e6e0680d8e5
说明:接口拦截器拦截的是/manger/**下的所有路径,我们想要访问就需要在接口上加上token和timestamp时间戳参数即可正常访问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值