SpringBoot极简教程 · Spring Boot

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

2020-03-17  本文已影响0人  zhangweisep

拦截器配置

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>
上一篇下一篇

猜你喜欢

热点阅读