zoukankan      html  css  js  c++  java
  • 使用session共享实现单点登录

    应用场景:

      用户服务实现用户登录将信息保存到session中,订单服务需要获取用户登录的session对象进行其他操作

    用户服务中,验证密码输入正确进去首页

    1、加入redis的session共享依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- session共享的依赖 -->
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>

    2、保存在session中

    session.setAttribute("user",user);

    发现在其他服务中拿不到用一个session值

    解决方法:

    在创建session服务的服务中:

    1、加入session共享依赖

    2、配置redis服务器的配置

    spring:
      #redis相关的信息
      redis:
        host: 127.0.0.1
        port: 6381
      main:
        allow-bean-definition-overriding: true

    3、在启动类中加入注解

    @EnableRedisHttpSession(redisFlushMode= RedisFlushMode.IMMEDIATE)
    public class StockUserApplication {。。。}

    4、在服务中加入这个 FeignClientsConfigurationCustom 配置类

    @Configuration
    @EnableFeignClients
    public class FeignClientsConfigurationCustom implements RequestInterceptor {
        @Override
        public void apply(RequestTemplate template) {
    
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            if (requestAttributes == null) {
                return;
            }
    
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            Enumeration<String> headerNames = request.getHeaderNames();
            if (headerNames != null) {
                while (headerNames.hasMoreElements()) {
                    String name = headerNames.nextElement();
                    Enumeration<String> values = request.getHeaders(name);
                    while (values.hasMoreElements()) {
                        String value = values.nextElement();
                        template.header(name, value);
                    }
                }
            }
            String sessionId = request.getSession().getId();
            if (sessionId != null) {
                template.header("Cookie", "SESSION=" + base64Encode(request.getSession().getId()));
            }
        }
        @Bean
        public FeignHystrixConcurrencyStrategy feignHystrixConcurrencyStrategy() {
            return new FeignHystrixConcurrencyStrategy();
        }
    
        public static String base64Encode(String value) {
            byte[] encodedCookieBytes = Base64.getEncoder().encode(value.getBytes());
            return new String(encodedCookieBytes);
    
        }
    View Code

    在加上这个类:

    /**
     * 熔断机制会导致feign之间session失效,使用此策略来解决问题
     */
    public class FeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
        private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategy.class);
        private HystrixConcurrencyStrategy delegate;
    
        public FeignHystrixConcurrencyStrategy() {
            try {
                this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
                if (this.delegate instanceof FeignHystrixConcurrencyStrategy) {
                    // Welcome to singleton hell...
                    return;
                }
                HystrixCommandExecutionHook commandExecutionHook =
                        HystrixPlugins.getInstance().getCommandExecutionHook();
                HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
                HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
                HystrixPropertiesStrategy propertiesStrategy =
                        HystrixPlugins.getInstance().getPropertiesStrategy();
                this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy);
                HystrixPlugins.reset();
                HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
                HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
                HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
                HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
                HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
            } catch (Exception e) {
                log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
            }
        }
    
        private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,
                                                     HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) {
            if (log.isDebugEnabled()) {
                log.debug("Current Hystrix plugins configuration is [" + "concurrencyStrategy ["
                        + this.delegate + "]," + "eventNotifier [" + eventNotifier + "]," + "metricPublisher ["
                        + metricsPublisher + "]," + "propertiesStrategy [" + propertiesStrategy + "]," + "]");
                log.debug("Registering Sleuth Hystrix Concurrency Strategy.");
            }
        }
    
        @Override
        public <T> Callable<T> wrapCallable(Callable<T> callable) {
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            return new WrappedCallable<>(callable, requestAttributes);
        }
    
        @Override
        public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
                                                HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize,
                                                HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
            return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime,
                    unit, workQueue);
        }
    
        @Override
        public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
                                                HystrixThreadPoolProperties threadPoolProperties) {
            return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);
        }
    
        @Override
        public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
            return this.delegate.getBlockingQueue(maxQueueSize);
        }
    
        @Override
        public <T> HystrixRequestVariable<T> getRequestVariable(HystrixRequestVariableLifecycle<T> rv) {
            return this.delegate.getRequestVariable(rv);
        }
    
        static class WrappedCallable<T> implements Callable<T> {
            private final Callable<T> target;
            private final RequestAttributes requestAttributes;
    
            public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
                this.target = target;
                this.requestAttributes = requestAttributes;
            }
    
            @Override
            public T call() throws Exception {
                try {
                    RequestContextHolder.setRequestAttributes(requestAttributes);
                    return target.call();
                } finally {
                    RequestContextHolder.resetRequestAttributes();
                }
            }
        }
    View Code

    在调用session服务的服务中:

      做相同的配置即可拿到同一个sessionId

    //从session域里获取到用户所有信息
    T_user sessionUser = (T_user) session.getAttribute("user");
  • 相关阅读:
    zookeeper记录2(选举模式和ZooKeeper的集群安装)
    端口复用技术简单了解;重用端口;socket复用端口
    java线程池如何合理配置核心线程数?(转)
    数据库锁机制(转)
    mysql左连接锁表_不得不会的mysql锁(转)
    POI: calculated end index (4361) is out of allowable range (4339..4358)
    jdbcTemplate事务管理
    springboot 访问静态资源
    springboot集成持久化框架
    第六章 FreeBSD之配置日期和时间
  • 原文地址:https://www.cnblogs.com/64Byte/p/13419958.html
Copyright © 2011-2022 走看看