基于Spring的拦截器实现(个人学习记录)

1Controller

@ApiOperation(value = "登录")
    @PostMapping("/User/login")
    public Result login(String username, String password, HttpSession session,HttpServletRequest request) {
        Integer flat=0;
        Cookie rcookie = null;
        Cookie[] cookies=request.getCookies();
        for (Cookie x:cookies) {
            if(x.getName().equals("token"))
            {
                rcookie=x;
                flat=1;
                System.out.println("存在"+rcookie.getName()+" "+rcookie.getValue());
                break;
            }
        }
        if(flat==0)
        {
            System.out.println(username+ " "+password);
            //用户信息
            User user = userService.login(username,password);
            System.out.println(user.getPassword());
            //账号不存在、密码错误
            if (user == null || !user.getPassword().equals(userService.getMd5Password(password, user.getSalt()))) {
                return Result.build(202, "用户名或密码错误");
            } else {
                //生成token,并保存到数据库
                String token = authService.createToken(user);
                TokenVO tokenVO = new TokenVO();
                tokenVO.setToken(token);

                User data = userService.login(username, password);

                session.setAttribute("uid", data.getUid());
                session.setAttribute("username", data.getUsername());
                return Result.ok(tokenVO);
            }
        }
        else {
            String token=rcookie.getValue();
            User user=authService.findByToken(token);
            if(user==null)return Result.build(201, "token验证失败");
            else {
                User data = userService.login(username, password);
                session.setAttribute("uid", data.getUid());
                session.setAttribute("username", data.getUsername());
                String newtoken = authService.createToken(user);
                TokenVO tokenVO = new TokenVO();
                tokenVO.setToken(newtoken);
                return Result.ok(tokenVO);
            }
        }
    }
    @GetMapping("/User/logout")
    public Result logout(HttpSession session, HttpServletRequest request)
    {
        session.invalidate();
        String token = TokenUtil.getRequestToken(request);
        authService.logout(token);
        return Result.build(214, "没有登录");
    }

2自定义拦截器

public class AuthInterceptor implements HandlerInterceptor {
    @Autowired
    private AuthService authService;

    @Override
    //preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用。
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        String token = TokenUtil.getRequestToken(request);
        System.out.println(token);
        //1. 根据token,查询用户信息
        User userEntity = authService.findByToken(token);
        //2. 若用户不存在,
        if (userEntity == null&&token!=null) {
            setReturn(response, 400, "用户不存在");
            return false;
        }
        //3. token失效
        if (token!=null&&userEntity.getExpiretime().isBefore(LocalDateTime.now())) {
            setReturn(response, 400, "用户登录凭证已失效,请重新登录");
            return false;
        }
        return true;
    }
//(2)这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。

postHandle是进行处理器拦截用的,它的执行时间是在处理器进行处理之后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的渲染之前执行,也就是说在这个方法中你可以对ModelAndView进行操作。
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {

    }3)该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。

//该方法将在整个请求完成之后,也就是DispatcherServlet渲染了视图执行。
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {

    }

    private static void setReturn(HttpServletResponse response, int status, String msg) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtil.getOrigin());
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setStatus(400);
        response.setContentType("application/json;charset=utf-8");
        Result build = Result.build(status, msg);
        String json = JSON.toJSONString(build);
        httpResponse.getWriter().print(json);
    }

}

自定义视图

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {


    @Bean
    public AuthInterceptor authInterceptor() {
        return new AuthInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> patterns = new ArrayList();
        patterns.add("/webjars/**");
        patterns.add("/druid/**");
        patterns.add("/sys/login");
        patterns.add("/swagger/**");
        patterns.add("/v2/api-docs");
        patterns.add("/swagger-ui.html");
        patterns.add("/swagger-resources/**");
        patterns.add("/api/User/login");

        registry.addInterceptor(authInterceptor()).addPathPatterns("/**").excludePathPatterns(patterns);
    }
}

User实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User  implements Serializable {
    private Integer uid;
    private String username;
    private String password;
    private String salt;
    private String phone;
    private String avatar;
    private Integer status;
    private String token;
    private LocalDateTime expiretime;
    private LocalDateTime logintime;
}

tokenVO类

@Data
public class TokenVO {
    private String token;
    private LocalDateTime expireTime;
}

TokenUtil

public class TokenUtil {
    /**
     * 获取请求的token
     */
    public static String getRequestToken(HttpServletRequest httpRequest) {

        //从header中获取token
        String token = httpRequest.getHeader("token");
        //如果header中不存在token,则从参数中获取token
        if (StringUtils.isBlank(token)) {
            token = httpRequest.getParameter("token");
        }
        return token;
    }
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值