找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

280

积分

0

好友

40

主题
发表于 昨天 02:39 | 查看: 7| 回复: 0

在我过去的工作中,曾遇到一个难题——内部系统越来越多,后台链接散落各地。

随着公司逐步推行微服务架构和私有化部署,多个后台系统逐渐成为日常工作的一部分,且没有统一入口,导致团队成员甚至老板都频繁询问后台地址和登录信息。尤其是在换设备或清理浏览器缓存后,后台入口常常一片迷雾,效率低下且繁琐。

所以,我设计了一个“统一门户管理中心”,用来集中管理所有子系统的登录和权限。

从需求到设计

思路碰撞

首先,明确需求:

  • 多后台:公司多个子系统部署,技术栈各异,管理成本巨大。
  • 统一入口:让员工登录一次后,便能访问所有有权限的子系统。
  • 低成本接入:避免每个子系统都进行大规模重构,减轻开发负担。

我最初考虑了 SSO(单点登录)方案,但发现传统的 SSO 协议虽然广泛应用,但对我们这样的内部系统来说,过于复杂且增加开发成本。

权衡与选择

通过多次对比,我最终决定采用“门户为中心”的方式,在统一入口实现登录,避免对每个子系统进行繁琐的改造。用户在门户登录后,生成一次性授权码,子系统只需用该授权码获取用户信息,并生成本地 token。

核心优势:

  1. 用户体验:登录一次后,便可访问多个后台,简化流程。
  2. 低成本接入:无需每个子系统改造,只需轻量级接入。
  3. 灵活性:适应不同的技术栈(Java、PHP、Go)和环境。
  4. 安全性:每次登录生成唯一授权码,有效期短,避免重放攻击。

后台设计思路

为了实现统一门户,我将其拆分为以下几个模块:

  1. 主页(系统入口总览):展示所有可访问的系统入口,用户点击后,通过生成一次性授权码跳转到子系统。
  2. 用户管理:统一管理公司员工的账号信息、权限设置和安全控制。
  3. 系统管理(子系统注册):为每个子系统注册信息,包括系统名称、URL、状态等。
  4. 系统健康检查:定期检查子系统是否在线,确保系统的可用性。
  5. 用户授权:控制每个员工可以访问哪些后台系统。
  6. IP白名单控制:增加额外的安全性,限制只有公司网络或特定IP才能访问。
  7. 操作日志:记录每个操作,方便审计和排查。

统一门户架构设计图

无感接入,轻松实现

系统接入

对于每个子系统的接入,我采取了封装SDK的方式。无论是Java、Go、PHP语言的项目,接入都十分简便。只需引入统一的 SDK,配置相关参数,便可自动接入统一门户,实现免登录。

对于第三方工具(如 Jenkins、GitLab),则采用轻量级通行证模式,模拟登录状态,避免改动过多。

单点退出

为了确保一致性和安全性,我在系统中实现了单点退出(SSO Logout)功能。用户在门户退出时,所有相关子系统都能即时响应,强制下线,保证了安全性与用户体验的一致性。

实现:

  1. 认证中心退出:用户退出时,系统在 Redis 中写入退出标记。
  2. 子系统拦截器:每个子系统会检查 Redis 中的退出标记,确保用户退出后无法再继续访问。

系统健康监控

健康监控是一个额外但关键的功能。我们利用健康检查接口定时探测每个子系统的在线状态,确保任何子系统宕机时,能第一时间通知管理员,避免误导用户。

系统健康监控示意图

高效的接口与管理

后端设计

在后端,我们实现了以下两个关键接口:

  1. 创建授权码接口(/sso/code/create):生成一次性授权码,供子系统验证使用。
  2. 校验授权码接口(/sso/code/verify):子系统拿到授权码后,向认证中心验证该码是否有效,并返回用户信息。

1. 创建授权码接口(/sso/code/create)

接口流程:

  • 用户在门户点击某个系统卡片,门户向认证中心请求生成授权码。
  • 前端接收到授权码后,跳转到子系统。
@Override
public Map<String, Object> createCode(HttpServletRequest request, Map<String, Object> body) {
    Long userId = (Long) request.getAttribute("userId");
    if (userId == null) {
        throw new RuntimeException("未登录或 Token 无效");
    }
    String appId = body.get("appId").toString();
    SysApplication app = applicationMapper.selectByAppId(appId);
    if (app == null) throw new RuntimeException("应用不存在:" + appId);
    if (!userHasPermission(userId, appId)) {
        throw new RuntimeException("用户无权访问系统:" + appId);
    }
    // 生成授权码
    String code = UUID.randomUUID().toString().replace("-", "");
    String authRedisKey = SsoRedisKeys.authCode(code);
    Map<String, Object> authInfo = new HashMap<>();
    authInfo.put("userId", userId);
    authInfo.put("appId", appId);
    redisUtils.set(authRedisKey, authInfo, 60); // 设置 60 秒过期
    Map<String, Object> result = new HashMap<>();
    result.put("code", code);
    result.put("expire", 60);
    return result;
}

2. 校验授权码接口(/sso/code/verify)

接口流程:

  • 子系统收到授权码后,向认证中心验证该授权码的有效性,并获取用户信息。
public Map<String, Object> verifyCode(HttpServletRequest request, Map<String, Object> body) {
    String code = String.valueOf(body.get("code"));
    String appId = String.valueOf(body.get("appId"));
    // 校验授权码是否有效
    String redisKey = SsoRedisKeys.authCode(code);
    Map<String, Object> authInfo = redisUtils.getObject(redisKey, Map.class);
    if (authInfo == null) {
        throw new RuntimeException("授权码无效或已过期");
    }
    // 校验 appId
    String storedAppId = (String) authInfo.get("appId");
    if (!appId.equals(storedAppId)) {
        throw new RuntimeException("授权码与应用不匹配");
    }
    // 查询用户信息
    Long userId = Long.parseLong(authInfo.get("userId").toString());
    User user = userMapper.selectById(userId);
    if (user == null) {
        throw new RuntimeException("用户不存在");
    }
    redisUtils.delete(redisKey); // 使用后删除授权码
    Map<String, Object> result = new HashMap<>();
    result.put("userId", user.getId());
    result.put("username", user.getUsername());
    result.put("appId", appId);
    return result;
}

通过上述两个接口,门户系统和各子系统之间可以实现快速、轻量的单点登录,同时保持子系统的独立性,且无需复杂的技术栈改造。

数据结构与设计

为确保系统稳定运行,我设计了四张核心数据表:用户信息表、系统分类表、系统信息表和用户授权关系表。这些表实现了账户管理、系统分类、授权分配等关键功能,使得每个模块的管理都能轻松扩展。

核心数据表设计

总结

通过统一门户 + 轻量化 SSO的设计,我们的系统能够在多后台、多语言、多环境的公司中高效运作。

最重要的是,这套方案的扩展性非常强,后期新系统的接入非常简单,能快速满足公司业务的不断扩展。随着企业规模的增长,我们也可以进一步对系统进行优化,增加更多的功能,如后台导航、系统通知、权限控制等,进一步提升使用体验。

这套方案的关键在于简洁、高效、灵活,适用于大多数中小型企业,尤其是在多技术栈、多后台的环境下,既能统一管理,又不强制改变每个子系统的原有登录体系,确保了系统的独立性与统一性。

您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-3 16:35 , Processed in 0.059355 second(s), 39 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表