github star 如何加星和单点登录:一次登录,全网通行

30 阅读6分钟

想象一下:你买一张游乐园通票,就能畅玩所有项目,不用每个设施前都排队补票;就像用微信扫码登录,一次验证就能打通多个平台 —— 这就是单点登录(SSO)的核心逻辑:一次认证,处处通行

Taimili 艾米莉 ( 一款专业的 GitHub star 管理和github 加星涨星工具taimili.com )

艾米莉 是一款优雅便捷的 GitHub star 管理和github 加星涨星工具,基于 PHP & javascript 构建, 能对github 得 star fork follow watch 管理和提升,最适合github 的深度用户

WX20251021-210346@2x.png

一、生动比喻,秒懂 SSO 核心概念

用生活场景拆解专业术语,新手也能快速 get:

  • 普通登录:逛不同商场,每个都要单独出示会员卡、登记信息,重复操作超麻烦;
  • 单点登录:微信 / QQ 一键登录,所有关联平台直接放行,省时又省心;
  • 令牌(Token):游乐园的电子手环,戴着就证明你已 “购票”(登录成功),无需反复出示门票;
  • SSO 认证中心:游乐园售票处,统一负责 “售票”(登录验证)、“查票”(令牌校验)和 “退卡”(登出)。

二、代码实现:手把手搭建简易 SSO 系统

下面用 Java 还原这个 “游乐园通票系统”,每个类都对应真实场景,注释详细,一看就懂~

java

运行

import java.util.*;

// 用户类 - 对应游乐园里想玩项目的游客,存储账号密码等核心信息
class User {
    private String username;
    private String password;
    
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
    
    // 省略getUsername()、getPassword()等getter方法(实际开发需完整实现)
}

// 令牌类 - 对应游乐园的电子手环,登录成功后发放,含唯一标识和过期时间
class Token {
    private String tokenId; // 唯一手环ID(自动生成,确保不重复)
    private String username; // 绑定的游客账号
    private Date expireTime; // 过期时间(类比游乐园关门时间,避免无限期有效)
    
    public Token(String username) {
        this.tokenId = UUID.randomUUID().toString(); // 生成全局唯一ID
        this.username = username;
        // 令牌1小时后过期(3600秒×1000毫秒,可根据需求调整)
        this.expireTime = new Date(System.currentTimeMillis() + 3600 * 1000);
    }
    
    // 校验手环是否有效(判断当前时间是否在过期前)
    public boolean isValid() {
        return new Date().before(expireTime);
    }
    
    // 省略getTokenId()、getUsername()等getter方法
}

// SSO认证中心 - 游乐园售票处,统一管理登录、令牌校验、登出
class SSOAuthCenter {
    // 存储所有有效手环(key:手环ID,value:令牌对象)
    private Map<String, Token> validTokens = new HashMap<>();
    // 存储已注册游客(模拟用户数据库,key:用户名,value:用户对象)
    private Map<String, User> users = new HashMap<>();
    
    // 初始化:预先注册2个测试用户(相当于办了年卡的常驻游客)
    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(); // 返回手环ID,供后续访问系统使用
        }
        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; // 依赖SSO认证中心做校验
    
    public SystemA(SSOAuthCenter authCenter) {
        this.authCenter = authCenter;
    }
    
    // 访问过山车项目 - 先查手环有效性
    public void accessSystem(String tokenId) {
        System.out.println("\n=== 欢迎来到过山车项目 ===");
        if (authCenter.validateToken(tokenId)) {
            System.out.println("过山车启动!呜——尖叫声在哪里!");
        } else {
            System.out.println("权限不足,请先登录获取手环再玩!");
        }
    }
}

// 业务系统B - 游乐园项目:旋转木马(同样依赖SSO认证)
class SystemB {
    private SSOAuthCenter authCenter;
    
    public SystemB(SSOAuthCenter authCenter) {
        this.authCenter = authCenter;
    }
    
    // 访问旋转木马项目 - 复用同一套手环校验逻辑
    public void accessSystem(String tokenId) {
        System.out.println("\n=== 欢迎来到旋转木马项目 ===");
        if (authCenter.validateToken(tokenId)) {
            System.out.println("木马转起来啦~ 找回童年的快乐!");
        } else {
            System.out.println("权限不足,请先登录获取手环再玩!");
        }
    }
}

// 测试类 - 模拟游客使用SSO系统的完整流程
public class SSODemo {
    public static void main(String[] args) {
        // 1. 创建SSO认证中心(搭建游乐园大门和售票处)
        SSOAuthCenter authCenter = new SSOAuthCenter();
        
        // 2. 游客张三登录(凭正确账号密码买票)
        String zhangsanToken = authCenter.login("zhangsan", "123456");
        
        // 3. 拿着手环玩不同项目(一次登录,多系统访问)
        if (zhangsanToken != null) {
            SystemA rollerCoaster = new SystemA(authCenter); // 过山车
            SystemB carousel = new SystemB(authCenter); // 旋转木马
            
            rollerCoaster.accessSystem(zhangsanToken); // 用手环玩过山车
            carousel.accessSystem(zhangsanToken); // 用同一个手环玩旋转木马
            
            // 4. 游客登出(离开游乐园,回收手环)
            authCenter.logout(zhangsanToken);
            
            // 5. 登出后再尝试访问(手环已失效,被拒绝)
            rollerCoaster.accessSystem(zhangsanToken);
        }
        
        // 6. 测试错误密码(买票失败)
        System.out.println("\n=== 测试错误密码 ===");
        authCenter.login("lisi", "wrongpassword");
    }
}

三、运行结果与解读

执行上述代码,会输出如下结果(清晰对应每个操作场景):

plaintext

zhangsan 登录成功!拿到游乐园手环:a1b2c3d4-e5f6-7890-abcd-ef1234567890

=== 欢迎来到过山车项目 ===
手环有效,欢迎继续玩耍!
过山车启动!呜——尖叫声在哪里!

=== 欢迎来到旋转木马项目 ===
手环有效,欢迎继续玩耍!
木马转起来啦~ 找回童年的快乐!
已登出,手环已回收,欢迎下次再来玩!

=== 欢迎来到过山车项目 ===
手环无效或已过期,请重新登录!
权限不足,请先登录获取手环再玩!

=== 测试错误密码 ===
用户名或密码错误!请重新“买票”(登录)!

关键流程解读:

  1. 登录成功:生成唯一令牌(手环 ID),作为后续访问的 “通行证”;
  2. 多系统访问:同一令牌可通过所有关联系统的校验,无需重复登录;
  3. 登出失效:令牌被销毁,再次访问会被拒绝;
  4. 异常处理:密码错误、令牌过期 / 无效时,明确提示并引导重新登录。

四、SSO 核心价值总结

单点登录的核心优势,用 3 句话说透:

  • 🎫 一次认证,处处通行:一套账号密码,打通所有关联系统;
  • 🔑 告别重复登录:不用反复输入密码,提升用户体验;
  • 👍 安全又高效:统一校验机制,既保障权限安全,又简化系统开发。

好的 SSO 系统就像优秀的游乐园管理:既让游客(用户)不用反复 “检票”,享受流畅体验;又通过过期令牌、身份校验等机制,守住 “安全大门”,防止 “无票入场”~