会话共享与单点登录(微服务)

一、单体应认证

在这里插入图片描述
在传统的单体应用中,用户的认证过程非常简单,cookie保存在用户自己的浏览器本地,session保存在服务器本地,只要在各自设定的有效期内,都能便捷的实现随取随用。
但在微服务架构中将变得不在那么容易,微服务本着服务自治的理念,服务被拆分为多个单体服务,并将这些不同的服务运行在不同的主机上,而且有时候由于高并发的需求,某个服务可能部署了多个实例,这些服务都需要进行用户的认证以及权鉴;

二、微服务会话共享

1、方案一

在这里插入图片描述
如图电商的微服务中,有专为用户认证提供的认证服务-----认证中心
用户通过网关访问认证中心,在认证中心中,进行用户认证以及权鉴,通过后生成session,以及cookie,cookie随响应返回给用户,保存在用户的浏览器上,而session将被同步到微服务集群中的每一个实例上,用户下次访问是携带cookie将可以访问任意一个服务

  • 优点:
    该同步很简单不需要大量的代码,只需在Tomcat配置文件中添加相应的配置即可
  • 缺点:
    在用户量比较大时,需要同步大量的数据,并且造成系统的数据的大量冗余,而且维护这么多数据的一致性等,浪费大量的系统资源

注意:

在添加返回cookie时,必须保证该cookie可以共享在域名的所有子域中并且作用的路径为/
否则不能访问其他服务

1、什么是子域

如:taobao.com为根
那么:
—— pay.taobao.com
—— member.taobao.com
—— wuliu.taobao.com
都为taobao.com的子域
所以要将cookie的作用域提高到taobao.com上,才能共享到各个子域,将作用路径设置为/,在访问时才会被请求带上

Cookie cookie = new Cookie("Tocken",tocken);
cookie.setDomain("taobao.com");
cookie.setPath("/");
response.addCookie(cookie);

方案二

spring cloud为我们提供了较为简单的解决方案----springSession + redis来实现session的全局共享,数据只需要保存一份,便可全局访问
在这里插入图片描述
用户认证通过之后,将数据保存在redis内存数据库中,用户会访问时将携带的cookie带到服务后,从redis中查找session,获取用户的信息

spring-session使用

1、导入依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<dependency>
 <groupId>org.springframework.session</groupId>
 <artifactId>spring-session-data-redis</artifactId>
</dependency>

2、application.yml配置

spring:
  application:
    name: gulimail-member
  cloud:
    nacos:
      discovery:
        server-addr: http://192.168.244.10:8848
  thymeleaf:
    cache: false
  redis:
    host: 192.168.244.10
    port: 6379
  session:
    store-type: redis

前提安装了redis服务

业务代码

登录

    public String toLogin(AuthUser authUser, HttpServletResponse response,HttpSession session){
        User user = userServer.AuthUserLogin(authUser);
        if (user == null){
            return "redirect:/login/login";
        }
        String tocken = user.getPassWord();
        redisTemplate.opsForValue().set("Tocken",tocken);
        Cookie cookie = new Cookie("Tocken",tocken);
        cookie.setDomain("taobao.com");
        cookie.setPath("/");
        response.addCookie(cookie);
        session.setAttribute("user",user);
        return "redirect:/main";
    }

登录后访问其他服务的主页

@GetMapping("/main")
    public String main(HttpSession session, Model model,@CookieValue(value = "Tocken",required = false)String Tocken){

        String redistocken = (String) redisTemplate.opsForValue().get("Tocken");

        if(redistocken!=null && redistocken.equals(Tocken)){
            model.addAttribute("user",session.getAttribute("user"));
            return "main";
        }
        return "redirect:/login/login";
        }

在将user保存在redis时必须要实例化,user实现实例化接口

@Data
public class User implements Serializable {
    private String Id;
    private String UserName;
    private String PassWord;
    private String Sex;
    private Date BrithDay;
    private String Avatar;
    private String Iphone;
    private String WeChart;
    private String address;
    private String IdentityNumber;
}

spring-session的配置类

@Configuration
public class SpringSessionConfig {

    @Bean
    public CookieSerializer cookieSerializer(){
        DefaultCookieSerializer defaultCookieSerializer = new DefaultCookieSerializer();
        defaultCookieSerializer.setDomainName("taobao.com");
        defaultCookieSerializer.setCookieName("TAOBAO");
        return  defaultCookieSerializer;
    }

    @Bean
    public RedisSerializer<Object> redisSerializer(){
        return new GenericJackson2JsonRedisSerializer();
    }
}

便可实现会话的共享与单点登录
上述代码中设置了两个cookie,前一个是本人在测试单点登录时编写,其实会话共享和单点登录使用一个springSession的cookie即可。

springSession原理

springSession其实是使用拦截器对HttpServletRequest和HttpServletResponse进行了分装,将具体的业务逻辑进行了替换而已

分析源码,在拦截器中访问了redis数据库将HttpSession中的数据进行了更新

在每个使用springSession的服务中都要导入上述依赖和配置。

单点登录方案

所谓的单点登录就是一处认证通过,其他服务皆放行

认证后将cookie发给用户,session实现共享,用户带着cookie即可访问任意服务

上述会话共享方案就是单点登录的雏形。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值