基于springboot完成拦截器,自定义登入检验注解

基于springboot完成拦截器,自定义登入检验注解

前文

拦截器类似与面向切面编程(aop)思想,拦截器则可以通过IoC容器来管理,因此可以通过注入等方式来获取其他Bean的实例。在请求前通过拦截器验证

集成拦截器

配置拦截器

import com.auth0.jwt.exceptions.JWTDecodeException;
import com.df.samplesub.annotation.PassToken;
import com.df.samplesub.annotation.UserLoginToken;
import com.df.samplesub.entity.User;
import com.df.samplesub.exception.TokenException;
import com.df.samplesub.service.UserService;

import com.df.samplesub.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
* @Description: 
* @Param:
* @return:
* @Author: 
* @Date: 2021/5/31
*/

public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    UserService userService;
    //请求执行前
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
        String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
        // 如果不是映射到方法直接通过
        if (!(object instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) object;
        Method method = handlerMethod.getMethod();
        //检查是否有passtoken注释,有则跳过认证
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        //检查有没有需要用户权限的注解
        if (method.isAnnotationPresent(UserLoginToken.class)) {
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
            if (userLoginToken.required()) {
                // 执行认证
                if (token == null) {
                    throw new TokenException("无token,请重新登录");
                }
                // 获取 token 中的 user id
                String userId;
                try {
                    //userId = JWT.decode(token).getAudience().get(0);
                    userId = JwtUtil.getUserId(token);

                } catch (JWTDecodeException j) {
                    throw new RuntimeException("401");
                }
                User user = userService.findUserById(userId);
                if (user == null) {
                    throw new TokenException("用户不存在,请重新登录");
                }
                // 验证 token
                //JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC512("www").build();
                JwtUtil.checkSign(token);
                return true;
            }
        }
        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 {
    }
}

自定义注解

1.免登入注解

2.登入注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @Description: 需要登录才能进行操作的注解UserLoginToken
* @Param:
* @return:
* @Author: 
* @Date: 2021/5/31
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserLoginToken {
    boolean required() default true;
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @Description: 过验证的PassToken
* @Param:
* @return:
* @Author: 
* @Date: 2021/5/31
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}

注册拦截器

两种方式:

package com.df.samplesub.config;

import com.df.samplesub.fiilter.AuthenticationInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Description: 注册拦截器
* @Param:
* @return:
* @Author: 
* @Date: 2021/6/9
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");   
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
}

2.启动类配置

//创建登录拦截器
@Bean
public CheckLoginInterceptor checkLoginInterceptor(){
    return new CheckLoginInterceptor();
}

//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(checkLoginInterceptor())
        .addPathPatterns("/**")  //拦截所有请求
        .excludePathPatterns("/users/regist")
        .excludePathPatterns("/users/login")
        .excludePathPatterns("/users/checkPhone")
        .excludePathPatterns("/users/sendVerifyCode")
    ;
}

测试

登入:创建token(此处使用的是jwt)

登入

免登入,不需要携带toktn

@PassToken
@GetMapping("/locationNames")
public ResultBean locationNames() {
    List<Arce> locationNames = arceService.getLocationNames();
    return ResultBean.success("查询成功",locationNames);
}

在这里插入图片描述

需要登入,必须携带有效token

@UserLoginToken
@GetMapping("/locationNames")
public ResultBean locationNames() {
    List<Arce> locationNames = arceService.getLocationNames();
    return ResultBean.success("查询成功",locationNames);
}

无token
在这里插入图片描述

正确的token
在这里插入图片描述

token错误或者过期
模拟token过期
在这里插入图片描述
效果
在这里插入图片描述
此处注销登入,删除缓存中token,将jwt中置为过期

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值