CorsWebFilter解决跨域,OncePerRequestFilter实现登录校验

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfig {
    /**
     * 该访问配置跨域访问执行
     */
    @Bean
    public CorsWebFilter corsWebFilter() {
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        //cors跨域配置对象
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.setAllowCredentials(true);//是否允许携带cookie
        corsConfiguration.addAllowedOrigin("*"); //允许跨域访问的域名,可填写具体域名,*代表允许所有访问
        corsConfiguration.addAllowedMethod("*");//允许访问类型:get  post 等,*代表所有类型
        corsConfiguration.addAllowedHeader("*");
        //配置源对象
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        //cors 过滤器对象  注意!CorsWebFilter不要导错包
        return new CorsWebFilter(urlBasedCorsConfigurationSource);
    }
}

 

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.servlet.HandlerExceptionResolver;
@Slf4j
@Order(1)
public class UserSessionFilter extends OncePerRequestFilter {

    @Autowired
    @Qualifier("handlerExceptionResolver")
    private HandlerExceptionResolver resolver;

    @Autowired
    private CommonRedisService commonRedisService;
    @Autowired
    private YmlConfig ymlConfig;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        log.info("====== UserSessionFilter =======");
        String uri = request.getRequestURI();
        log.info("uri: {}", uri);
        //无需登录的接口
        if (ymlConfig.getUnLoginUrlList().contains(uri)) {
            filterChain.doFilter(request, response);
            return;
        }
        //校验session
        HttpSession session = request.getSession(false);
        //游客放行但需要用户信息接口
        if (null == session && ymlConfig.getUnLoginNeedUserInfoUrlList().contains(uri)) {
            filterChain.doFilter(request, response);
            return;
        }
        if (null == session) {
            //提示重新登录
            resolver.resolveException(request, response,
                    null, new BusException(ErrorCodeEnum.USER_SESSION_ERROR, ErrorEnum.USER_SESSION_IS_ERROR));
            return;
        }
        Long userId = (Long) session.getAttribute(GlobalConst.USER_ID_STR);
        String loginSessionidKey = RedisKeyConst.USER_LOGIN_SESSIONID_KEY + userId;
        String loginSessionid = null != userId ? (String) commonRedisService.getValue(loginSessionidKey) : null;
        // userId为null表示当前客户端没有登录,redis 的Sessionid与当前 Sessionid不相等表示多端登录
        if (null == userId || StringUtils.isBlank(loginSessionid) ||
                ymlConfig.isEnnableLoginMany() ? false : !session.getId().equals(loginSessionid)) {
            //提示重新登录
            resolver.resolveException(request, response,
                    null, new BusException(ErrorCodeEnum.USER_SESSION_ERROR, ErrorEnum.USER_SESSION_IS_ERROR));
            return;
        }
        //session中获取
        String roleIdsJsonStr = session.getAttribute(GlobalConst.ROLE_ID_LIST_STR).toString();
        List<Integer> roleIds = JSON.parseArray(roleIdsJsonStr, Integer.class);

        UserRoleInfo userRoleInfo = new UserRoleInfo();
        userRoleInfo.setUserId(userId);
        userRoleInfo.setRoleIds(roleIds);
        //保存用户信息到ThreadLocal
        UserRoleInfoUtil.set(userRoleInfo); 

        //放行
        try {
            filterChain.doFilter(request, response);
        } finally {
            UserRoleInfoUtil.clear();//清除
        }

    }
}

public class UserRoleInfoUtil {

    private static final ThreadLocal<UserRoleInfo> currentUser = new ThreadLocal<>();

    public static UserRoleInfo get() {
        return currentUser.get();
    }

    public static void set(UserRoleInfo userRoleInfo) {
        currentUser.set(userRoleInfo);
    }

    public static void clear() {
        currentUser.remove();
    }
}

 

@EnableRedisHttpSession的使用,UserSessionFilter作为公共代码,以@Import的注册方式加入到需要Sesssion校验的微服务模块之中。

import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.session.FlushMode;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@Slf4j
@EnableRedisHttpSession(
        maxInactiveIntervalInSeconds = 28800,
        flushMode = FlushMode.ON_SAVE,
        redisNamespace = "spring:session:xxx.web.user")
@MapperScan("xxx.web.order.infrastructure.mapper")
@SpringBootApplication(scanBasePackages = {"xxx.web.order", "xxx.web.common"})
@EnableFeignClients(basePackages = "xxx.web.user.client.feign")
@Import(UserSessionFilter.class)
@EnableAspectJAutoProxy(exposeProxy=true)
public class OrderApplication implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

    @Override
    public void run(String... args) {
        log.info("----------------------OrderApplication Start Success----------------------");
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值