All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.spring.api.AbstractApiInterceptor Maven / Gradle / Ivy

There is a newer version: 2023.2.5
Show newest version
package shz.spring.api;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import shz.core.msg.ClientFailure;
import shz.core.msg.ClientFailureMsg;
import shz.core.msg.ServerFailureMsg;
import shz.core.net.api.ApiMethodAndPath;
import shz.spring.auth.AuthService;
import shz.spring.session.Session;
import shz.spring.session.SessionHolder;
import shz.spring.token.TokenIdentity;
import shz.spring.token.TokenInfo;
import shz.spring.token.TokenService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class AbstractApiInterceptor implements HandlerInterceptor, WebMvcConfigurer {
    protected final String appName;
    protected final AuthService authService;
    protected final TokenService tokenService;

    protected AbstractApiInterceptor(String appName, AuthService authService, TokenService tokenService) {
        this.appName = appName;
        this.authService = authService;
        this.tokenService = tokenService;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(this);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) return true;
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        ApiMethodAndPath methodAndPath = ApiMethodAndPathGetter.get(handlerMethod.getBeanType(), handlerMethod.getMethod());
        ClientFailure.BAD_METHOD.requireNonNull(methodAndPath);

        String method = methodAndPath.getMethod();
        String path = methodAndPath.getPath();
        if (ignore(appName, method, path)) return true;

        //获取当前会话
        Session session = SessionHolder.getNonNull(request);

        ApiDetail apiDetail = getApiDetail(appName, method, path);
        ServerFailureMsg.requireNonNull(apiDetail, "缺失API[appName:%s,method:%s,path:%s]", appName, method, path);

        //限流
        ClientFailure.TOO_MANY_REQUESTS.requireNon(apiDetail.getRateLimit() > 0 && rateLimit(apiDetail.getId(), apiDetail.getRateLimit()));

        //解析token
        TokenIdentity tokenIdentity = tokenService.getTokenIdentity(request);
        if (tokenIdentity != null) {
            session.setUserid(tokenIdentity.userid);
            session.setRoleId(tokenIdentity.roleId);
        }

        if (apiDetail.isLogin()) {
            TokenInfo tokenInfo = tokenService.getTokenInfo(tokenIdentity);
            ClientFailure.UNAUTHORIZED.requireNon(!tokenService.verify(tokenInfo, session));
            session.setLogin(tokenService.isLogin(tokenInfo));
            //登录验证
            ClientFailure.UNAUTHORIZED.requireNon(!session.getLogin());
            //权限验证
            authService.checkApiPermission(session.getRoleId(), apiDetail.getId());
        } else session.setLogin(tokenService.isLogin(session));
        session.setDba(authService.isDba(session.getRoleId()));

        //判断是否禁用
        ClientFailure.FORBIDDEN.requireNon(!apiDetail.isEnabled() && !session.isDba());

        //判断是否重复提交
        if (apiDetail.getIntervalLimit() > 0 && session.getUserid() != null)
            ClientFailureMsg.requireNon(intervalLimit(apiDetail.getId(), session.getUserid(), apiDetail.getIntervalLimit() * 1000L), "重复提交");

        return true;
    }

    protected abstract ApiDetail getApiDetail(String appName, String method, String path);

    protected boolean ignore(String appName, String method, String path) {
        return false;
    }

    protected boolean rateLimit(long apiId, int rateLimit) {
        return false;
    }

    protected boolean intervalLimit(long apiId, long userid, long intervalLimitMillis) {
        return false;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy