SSO单点登录—基于redis共享服务

传统登录

在传统的java项目登录验证机制只涉及到单系统,因此可以直接使用session或者cookie实现。(登录的流程是:用户填写用户名和密码信息登录,后台服务器判断用户信息是否正确;若信息正确,则存储用户信息到session或者cookie中(例如,存储用户名),后面该用户通过浏览器请求服务,服务器会通过session或者cookie中存储的用户信息,了解该用户已经登录并正常响应服务)

SSO单点登录

如今比较流行的分布式服务中,都是拥有若干个服务相互协助,完成一整个系统的工作。那么在分布式服务中,便会出现以下问题。

问题:

由于浏览器的同源策略(即相同协议、相同端口、相同域名),cookie无法在多个服务中共享用户信息(即当用户登录了一个服务,那么其他的服务是无法获取登录用户信息)。正是如此,便出现了sso单点登录。

解决方法:

sso单点登录需要解决两个方面问题:第一方面是多个服务共享登录用户信息;第二方面是一个用户在多个服务中的cookie信息相同。

一、多个服务共享登录用户信息:

我们可以将redis缓存作为一个单独的服务,通过key/value数据结构,用于存储登录后的用户信息,代码如下:
项目目录结构
redis服务提供的接口:

 @RestController
public class RedisServerController {

    @Autowired
    private RedisServerService redisServerService;

    @RequestMapping("/get")
    public String get(String key) {
        Object o = redisServerService.get(key);
        if (o != null) {
            String value = String.valueOf(o);
            return value;
        }
        return null;
    }

    @RequestMapping("/put")
    public String put(String key, String value, long seconds) {
        redisServerService.put(key, value, seconds);
        return "ok";
    }
}

redis服务的service实现类:

@Service
public class RedisServerServiceImpl implements RedisServerService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void put(String key, Object value, long seconds) {
        redisTemplate.opsForValue().set(key, value, seconds, TimeUnit.SECONDS);
    }

    @Override
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}

其他服务可以通过远程调用,获取redis服务中的用户信息。通过这样的一个设计,用户登录后,将用户信息存储到redis共享服务中,其他服务可以共享redis中的用户信息。

二、一个用户在多个服务中的cookie信息相同:

正是由于浏览器的同源策略,使得多个服务无法像单体系统一样,很容易获取cookie中的信息,那么如何在多个服务中获取相同的信息呢,其实有几种方法可以解决这个问题,例如:让多个服务的父域名相同、使用nginx反向代理多个服务、使用网关路由转发等。本章主要讲述使用网关解决浏览器的跨域问题,代码如下:
项目目录结构
网关路由信息配置(使用的是springcloud gateway网关):

server:
  port: 9090

spring:
  application:
    name: sso-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
      - id: sso-server
        uri: http://localhost:8080
        predicates:
        - Path=/sso-server/**
        filters:
        - StripPrefix=1
      - id: sso-client
        uri: http://localhost:8081
        predicates:
        - Path=/sso-client/**
        filters:
        - StripPrefix=1

通过统一网关路由配置,等同于“欺骗”浏览器所有服务都位于“一个服务”中,可以解决浏览器跨域问题。

github地址:https://github.com/crc982169622/sso-learn

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值