美文网首页SpringBoot极简教程 · Spring Boot
Spring Boot + redis 配置拦截器实现权限验证

Spring Boot + redis 配置拦截器实现权限验证

作者: zhangweisep | 来源:发表于2020-03-17 14:59 被阅读0次

    拦截器配置

    package com.yuhan.mkt.interceptor;
    
    import com.alibaba.fastjson.JSONObject;
    import com.yuhan.mkt.annotation.AuthToken;
    import com.yuhan.mkt.util.EmptyUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.context.ApplicationContext;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    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.io.PrintWriter;
    import java.lang.reflect.Method;
    import java.util.concurrent.TimeUnit;
    
    /**
     * Filename: ttee
     * Author:   Zhang Wei
     * Date:     2018/8/29 16:12
     * Description:
     * History:
     */
    @Slf4j
    public class AuthorizationInterceptor implements HandlerInterceptor {
    
    
        //存放鉴权信息的Header名称,默认是Authorization
        private String httpHeaderName = "Authorization";
    
        //鉴权失败后返回的错误信息,默认为401 unauthorized
        private String unauthorizedErrorMessage = "401 unauthorized";
    
        //鉴权失败后返回的HTTP错误码,默认为401
        private int unauthorizedErrorCode = HttpServletResponse.SC_UNAUTHORIZED;
    
        private static ApplicationContext applicationContext;
    
        private StringRedisTemplate stringRedisTemplate;
    
        public static void setStringRedisTemplate(ApplicationContext applicationContext){
            AuthorizationInterceptor.applicationContext = applicationContext;
        }
    
        /**
         * 存放登录用户模型Key的Request Key
         */
        public static final String REQUEST_CURRENT_KEY = "REQUEST_CURRENT_KEY";
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            stringRedisTemplate = applicationContext.getBean(StringRedisTemplate.class);
    
            if (!(handler instanceof HandlerMethod)) {
                return true;
            }
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method        method        = handlerMethod.getMethod();
            // 如果打上了AuthToken注解则需要验证token
            if (method.getAnnotation(AuthToken.class) != null || handlerMethod.getBeanType().getAnnotation(AuthToken.class) != null) {
    
                String token = request.getHeader(httpHeaderName);
                log.info("token is {}", token);
                String username = "";
                if (token != null && token.length() != 0) {
                    username = stringRedisTemplate.opsForValue().get(token);
                    Long tokeBirthTime = stringRedisTemplate.getExpire(token, TimeUnit.SECONDS);
    
                    log.info("redis缓存用户名 is {}", username);
                    log.info("过期时间 {}", tokeBirthTime);
                    if(tokeBirthTime > 0 && EmptyUtil.isNotEmpty(username)){
                        stringRedisTemplate.opsForValue().set(token, username, 60*60, TimeUnit.SECONDS);
                        request.setAttribute(REQUEST_CURRENT_KEY, username);
                        return true;
                    }
                }
                JSONObject jsonObject = new JSONObject();
                PrintWriter out = null;
                try {
                    response.setHeader("Access-Control-Allow-Origin", "*");
                    response.setStatus(unauthorizedErrorCode);
                    response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                    jsonObject.put("code", ((HttpServletResponse) response).getStatus());
                    jsonObject.put("message", HttpStatus.UNAUTHORIZED);
                    out = response.getWriter();
                    out.println(jsonObject);
                    return false;
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (null != out) {
                        out.flush();
                        out.close();
                    }
                }
            }
            request.setAttribute(REQUEST_CURRENT_KEY, null);
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    

    权限拦截自定义注解

    package com.yuhan.mkt.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Filename: ttee
     * Author:   Zhang Wei
     * Date:     2018/8/29 16:12
     * Description: 自定义注解(Token验证)
     * 使用该注解的类、方法等都需要经过Token验证
     * History:
     */
    
    @Target({ElementType.METHOD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AuthToken {
    
    }
    

    使用方法

    /**
         * 退出登录
         * 加入AuthToken注解的方法都会进入拦截器进行权限验证
         * @param userJson
         * @return
         * @throws Exception
         */
        @AuthToken
        @ApiOperation(value = "退出登录", notes = "param:UserJson")
        @RequestMapping(value = "/logout", method = RequestMethod.POST)
        public Object logout(@RequestBody UserJson userJson) throws Exception{
            if(EmptyUtil.isEmpty(userJson) || EmptyUtil.isEmpty(userJson.getToken())){
                return ResultUtil.error(ExceptionEnum.PARAM_NULL);
            }
            Result result = userService.logout(userJson);
            return result;
        }
    

    pom.xml依赖包

    <!--redis -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
            <!-- redis缓存 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-cache</artifactId>
            </dependency>
    

    相关文章

      网友评论

        本文标题:Spring Boot + redis 配置拦截器实现权限验证

        本文链接:https://www.haomeiwen.com/subject/fkdtyhtx.html