TokenAuthFilter 认证拦截器

本次项目中使用了认证拦截器来拦截非登录的请求,本来想通过@WebFilter来实现,但是发现没起作用,后面有时间换用@WebFilter注解实现。

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Slf4j
@Configuration
@Component
@WebFilter(urlPatterns = {"/merchant/*"}, filterName = "tokenAuthFilter",
        initParams = {
                @WebInitParam(name = "loginUI", value = "/merchant/login"),
                @WebInitParam(name = "captchaImage", value = "/merchant/captchaImage"),
                @WebInitParam(name = "encoding", value = "utf-8")
        })

@Order(1)
public class TokenAuthFilter implements Filter {

    private FilterConfig config;

    @Autowired
    private RedisService redisService;


    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse rep = (HttpServletResponse) response;
        // 设置允许跨域的配置
        // 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
        rep.setHeader("Access-Control-Allow-Origin", "*");
        // 允许的访问方法
        rep.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS");
        // Access-Control-Max-Age 用于 CORS 相关配置的缓存
        rep.setHeader("Access-Control-Max-Age", "3600");
        rep.setHeader("Access-Control-Allow-Headers", "token,Origin, X-Requested-With, Content-Type, Accept");
        rep.setCharacterEncoding("UTF-8");

        // 不带http://域名:端口的地址
        String uri = req.getRequestURI();
        if (uri.contains("/merchant/login") ||
                uri.contains("/merchant/captchaImage") ) {
            //如果是登录页,则放行调用登录方法
            // 请求登录,放行
            chain.doFilter(request, response);
        } else {
            //用头部进行校验是否用户登录,为了防止经常调用该接口,建议缓存
            String token = getToken(req);
            if (token != null && !"null".equals(token)) {
                String userName = (String) redisService.get(MERCHANT_USER_LOGIN + token);
                if (userName != null) {
                    if(uri.contains("/merchant/logout")) {
                        LoginContext.clearLoginUserName();
                        ServletUtils.renderString(rep, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功")));
                        return;
                    } else {
                        // 放入到ThreadLocal中
                        LoginContext.setLoginUserName(userName);
                    }
                    // 已经登录,放行进行业务请求
                    try {
                        chain.doFilter(req, rep);
                    } finally {
                        LoginContext.clearLoginUserName();
                    }
                } else {
                    AjaxResult.error("操作错误");
                    return;
                }
            } else {
                return;
            }
        }
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        this.config = config;
    }

    @Override
    public void destroy() {
        this.config = null;
    }


    /**
     * 获取请求token
     *
     * @param request
     * @return token
     */
    private String getToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (StringUtils.isNotEmpty(token) && token.startsWith("Bearer ")) {
            token = token.replace("Bearer ", "");
        }
        return token;
    }


}

LoginContext实现

public class LoginContext {
    private static final ThreadLocal<String> loginthreadLocal = new ThreadLocal<>();

    public static String getLoginUserName() {
        return loginthreadLocal.get();
    }

    public static void setLoginUserName(String userName) {
        loginthreadLocal.set(userName);
    }

    public static void clearLoginUserName() {
        loginthreadLocal.remove();
    }
}

你可能感兴趣的:(Java)