登录过程中的拦截(一)

需求:用户未登录时,只显示登录界面,登录后才能看到菜单及界面。
在后面每个controller接收客户端请求的方法上,都加上需要认证的注解。未登录的话,返回未登录返回码,客户端收到未登录返回码,则跳到登录界面

1.编写一个注解

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysToken {
    String value() default "true";
}

2.编写一个拦截器

@Component
public class AuthTokenInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (this.checkNrefreshAuthTocken(request, response, handler)) {
            return true;
        }
        return false;
    }

    private boolean checkNrefreshAuthTocken(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        if (!(handler instanceof HandlerMethod))
            return true;
        Map cookieAttr = null;
        PromiseUser promiseUser = null;
        Long loyalIdSetTime = null;
        try {
            cookieAttr = UserUtil.getLoginInfoFromRequest(request);
        } catch (InvalidSignatureException | UserNotLoginException e) {
            promiseUser = null;
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(500);
            return false;
        }
        if (!CollectionUtils.isEmpty(cookieAttr)) {
            promiseUser = (PromiseUser) cookieAttr.get("promiseUser");
            request.setAttribute("loyalPromiseUser", promiseUser);

            loyalIdSetTime = (Long) cookieAttr.get("loyalIdSetTime");
            request.setAttribute("loyalIdSetTime", (Long) cookieAttr.get("loyalIdSetTime"));
        }

        try {
            //刷新cookie,要在preHandle中做,不能在postHandle中做,因为postHandle中,response已经commit了
            refreshAuthTocken(response, promiseUser, loyalIdSetTime);

            AuthToken authToken = getAuthTokenAnnotation(handler);
            //如无注解,返回正常执行
            if (authToken == null)
                return true;

            //有注解,cookie信息无效
            if (CollectionUtils.isEmpty(cookieAttr) || promiseUser == null) {
                buildErrorResponseInfo(response);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            response.sendError(500);
            return false;
        }

        return true;
    }

    private void refreshAuthTocken(HttpServletResponse response, PromiseUser promiseUser, Long loyalIdSetTime) throws UnsupportedEncodingException, NoSystemPropertyException {
        if (promiseUser != null) {
            if (loyalIdSetTime == null)
                loyalIdSetTime = 0L;
            if ((System.currentTimeMillis() - loyalIdSetTime) >= Long.parseLong(SystemProperties.getProperty(SystemProperties.REFRESH_LOYAL_ID_TIME))) {
                UserUtil.buildLoginCookie(response, promiseUser);
            }
        }
    }

    private AuthToken getAuthTokenAnnotation(Object handler) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 获取方法上的注解
        AuthToken authToken = handlerMethod.getMethod().getAnnotation(AuthToken.class);
        // 如果方法上的注解为空 则获取类的注解
        if (authToken == null) {
            authToken = handlerMethod.getMethod().getDeclaringClass().getAnnotation(AuthToken.class);
        }
        return authToken;
    }

    private void buildErrorResponseInfo(HttpServletResponse response) throws IOException {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;

//        Map<String, String> resMap = new HashMap<String, String>();
//        resMap.put("result","fail");
//        resMap.put("returnCode","C100002");
//        resMap.put("message", ReturnCode.getMessage("C100002"));
        ServiceResponse result = new ServiceResponse();
        result.setStatus(ReturnCode.NOT_LOGIN);
        result.setMessage(ReturnCode.getMessage(ReturnCode.NOT_LOGIN));
        out = response.getWriter();
        out.append(JsonUtil.toJson(result));
    }
}

第三步:编写过滤器

@Configuration
public class SystemBluMvcConfig implements WebMvcConfigurer {
    @Bean
    public SysTokenInterceptor securityInterceptor() {
        return new SysTokenInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(securityInterceptor()).excludePathPatterns("/admin/login")
                .addPathPatterns("/**");
    }

    @Bean
    public CommonsMultipartResolver getCommonMultipartResolver() {
        return new CommonsMultipartResolver();
    }
}

第四步:在Controller类的方法中加注解

@SysToken
    @RequestMapping(path = "/menu", method = RequestMethod.GET)
    public ServiceResponse getAllMenuTree() {
	}

这样就可以了

发布了7 篇原创文章 · 获赞 0 · 访问量 133

猜你喜欢

转载自blog.csdn.net/HexString/article/details/104632743