单点登录:一次登录,全网通行

大家好,我是小悟。

  • 想象一下你去游乐园,买了一张通票(登录),然后就可以玩所有项目(访问各个系统),不用每个项目都重新买票(重新登录)。这就是单点登录(SSO)的精髓!

    SSO的日常比喻

    • 普通登录:像去不同商场,每个都要查会员卡
    • 单点登录:像微信扫码登录,一扫全搞定
    • 令牌:像游乐园手环,戴着就能证明你买过票

    下面用代码来实现这个"游乐园通票系统":

    代码实现:简易SSO系统

    typescript 复制代码
    import java.util.*;
    
    // 用户类 - 就是我们这些想玩项目的游客
    class User {
        private String username;
        private String password;
        
        public User(String username, String password) {
            this.username = username;
            this.password = password;
        }
        
        // getters 省略...
    }
    
    // 令牌类 - 游乐园手环
    class Token {
        private String tokenId;
        private String username;
        private Date expireTime;
        
        public Token(String username) {
            this.tokenId = UUID.randomUUID().toString();
            this.username = username;
            // 令牌1小时后过期 - 游乐园晚上要关门的!
            this.expireTime = new Date(System.currentTimeMillis() + 3600 * 1000);
        }
        
        public boolean isValid() {
            return new Date().before(expireTime);
        }
        
        // getters 省略...
    }
    
    // SSO认证中心 - 游乐园售票处
    class SSOAuthCenter {
        private Map<String, Token> validTokens = new HashMap<>();
        private Map<String, User> users = new HashMap<>();
        
        public SSOAuthCenter() {
            // 预先注册几个用户 - 办了年卡的游客
            users.put("zhangsan", new User("zhangsan", "123456"));
            users.put("lisi", new User("lisi", "abcdef"));
        }
        
        // 登录 - 买票入场
        public String login(String username, String password) {
            User user = users.get(username);
            if (user != null && user.getPassword().equals(password)) {
                Token token = new Token(username);
                validTokens.put(token.getTokenId(), token);
                System.out.println(username + " 登录成功!拿到游乐园手环:" + token.getTokenId());
                return token.getTokenId();
            }
            System.out.println("用户名或密码错误!请重新买票!");
            return null;
        }
        
        // 验证令牌 - 检查手环是否有效
        public boolean validateToken(String tokenId) {
            Token token = validTokens.get(tokenId);
            if (token != null && token.isValid()) {
                System.out.println("手环有效,欢迎继续玩耍!");
                return true;
            }
            System.out.println("手环无效或已过期,请重新登录!");
            validTokens.remove(tokenId); // 清理过期令牌
            return false;
        }
        
        // 登出 - 离开游乐园
        public void logout(String tokenId) {
            validTokens.remove(tokenId);
            System.out.println("已登出,欢迎下次再来玩!");
        }
    }
    
    // 业务系统A - 过山车
    class SystemA {
        private SSOAuthCenter authCenter;
        
        public SystemA(SSOAuthCenter authCenter) {
            this.authCenter = authCenter;
        }
        
        public void accessSystem(String tokenId) {
            System.out.println("=== 欢迎来到过山车 ===");
            if (authCenter.validateToken(tokenId)) {
                System.out.println("过山车启动!尖叫声在哪里!");
            } else {
                System.out.println("请先登录再玩过山车!");
            }
        }
    }
    
    // 业务系统B - 旋转木马
    class SystemB {
        private SSOAuthCenter authCenter;
        
        public SystemB(SSOAuthCenter authCenter) {
            this.authCenter = authCenter;
        }
        
        public void accessSystem(String tokenId) {
            System.out.println("=== 欢迎来到旋转木马 ===");
            if (authCenter.validateToken(tokenId)) {
                System.out.println("木马转起来啦!找回童年记忆!");
            } else {
                System.out.println("请先登录再玩旋转木马!");
            }
        }
    }
    
    // 测试我们的SSO系统
    public class SSODemo {
        public static void main(String[] args) {
            // 创建认证中心 - 游乐园大门
            SSOAuthCenter authCenter = new SSOAuthCenter();
            
            // 张三登录
            String token = authCenter.login("zhangsan", "123456");
            
            if (token != null) {
                // 拿着同一个令牌玩不同项目
                SystemA systemA = new SystemA(authCenter);
                SystemB systemB = new SystemB(authCenter);
                
                systemA.accessSystem(token);  // 玩过山车
                systemB.accessSystem(token);  // 玩旋转木马
                
                // 登出
                authCenter.logout(token);
                
                // 再尝试访问 - 应该被拒绝
                systemA.accessSystem(token);
            }
            
            // 测试错误密码
            authCenter.login("lisi", "wrongpassword");
        }
    }

    运行结果示例:

    diff 复制代码
    zhangsan 登录成功!拿到游乐园手环:a1b2c3d4-e5f6-7890-abcd-ef1234567890
    === 欢迎来到过山车 ===
    手环有效,欢迎继续玩耍!
    过山车启动!尖叫声在哪里!
    === 欢迎来到旋转木马 ===
    手环有效,欢迎继续玩耍!
    木马转起来啦!找回童年记忆!
    已登出,欢迎下次再来玩!
    === 欢迎来到过山车 ===
    手环无效或已过期,请重新登录!
    请先登录再玩过山车!
    用户名或密码错误!请重新买票!

    总结一下:

    单点登录就像:

    • 一次认证,处处通行 🎫
    • 不用重复输入密码 🔑
    • 安全又方便 👍

    好的SSO系统就像好的游乐园管理,既要让游客玩得开心,又要确保安全!

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。

您的一键三连,是我更新的最大动力,谢谢

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

相关推荐
葫芦和十三2 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp2 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑3 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯4 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan6 小时前
多Agent之间的区别
后端
青石路7 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充8 小时前
1.面向对象设计思想
后端
IT_陈寒8 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro9 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗9 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端