V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Canon1014
V2EX  ›  PHP

关于系统单点登录跪求一个方案

  •  
  •   Canon1014 · 2019-05-27 15:38:13 +08:00 · 5941 次点击
    这是一个创建于 2010 天前的主题,其中的信息可能已经有所发展或是发生改变。
    • 项目现在就是传统 WEB 站点,服务器就是普通 PHP+nginx+mysql+redis...
    • 将来可能会开发一个产品,用的是相同用户数据,决定把登录模块拆出来
    • 和一般单点登录不一样的是:在于这个项目不布置在公网,只有 IP 没有域名
    • 我尝试了:共享 sessionJWTCAS 三种方案
    • 都遇到了同样的问题就是站点不同 session 和 cookie 不能跨域或者获取,导致一边登录另一边没有登录状态
    • 我本地修改了 host 后以上三个方案都可以实现单点登录
    • 但是领导要求生产环境不考虑修改 host 或者内网 dns 的可能
    • 先感觉各位了,玻璃心菜鸡勿喷
    30 条回复    2020-06-24 16:59:51 +08:00
    zsc8917zsc
        1
    zsc8917zsc  
       2019-05-27 15:46:15 +08:00   ❤️ 1
    生产环境有域名解析自然不用 host 呀............
    或者用 Oauth2.0
    Canon1014
        2
    Canon1014  
    OP
       2019-05-27 15:48:54 +08:00
    @zsc8917zsc #1 感谢,在看 oauth2 了,总感觉还是少不了存储 token 的问题;因为项目部署都是在内网 没有域名的
    wangxiaoaer
        3
    wangxiaoaer  
       2019-05-27 15:51:43 +08:00   ❤️ 2
    你这种简单应用 cas 足够了。 另外,OAuth2 跟单点登陆是两个概念,不要搞混了。
    EasyProgramming
        4
    EasyProgramming  
       2019-05-27 18:22:17 +08:00   ❤️ 1
    使用 jwt 生成 token,然后把 token 存在 redis 上面,所以模块的登陆逻辑统一为从 redis 来获取 token 然后校验,这样也实现了单点登录
    wunonglin
        5
    wunonglin  
       2019-05-27 18:26:53 +08:00
    单点登录不就是存 redis 的时候

    ```
    // 多点
    // token = uid

    DOASJOJOJODAS = 1
    213321J3N312HH1 = 11
    ```
    // 单点
    // uid = token

    11 = DOASJOJOJODAS
    ```

    多点的时候存 token,里面是 uid
    单点的时候存 uid,里面是 token
    wunonglin
        6
    wunonglin  
       2019-05-27 18:27:40 +08:00   ❤️ 1
    ```
    // 多点
    // token = uid

    DOASJOJOJODAS = 1
    213321J3N312HH1 = 1
    ```
    ```
    // 单点
    // uid = token

    11 = DOASJOJOJODAS
    ```
    petelin
        7
    petelin  
       2019-05-27 18:45:44 +08:00
    你是想让一个地方登陆, 整个系统都登陆?
    zsc8917zsc
        8
    zsc8917zsc  
       2019-05-27 18:55:34 +08:00   ❤️ 1
    @Canon1014 内网部署的话你可以考虑 token 扔 url 上
    opengps
        9
    opengps  
       2019-05-27 18:58:23 +08:00 via Android
    用个数据库存 token,然后所有服务都链接这个数据库验证
    jaylee77
        10
    jaylee77  
       2019-05-27 18:58:40 +08:00
    你这个需求依赖 cookie,不配置域名做不到单点登入
    wunonglin
        11
    wunonglin  
       2019-05-27 19:04:15 +08:00   ❤️ 1
    @jaylee77 带 heade 就行了要啥 cookie ?
    ZSeptember
        12
    ZSeptember  
       2019-05-27 19:19:25 +08:00
    域名都不一样就没办法
    index90
        13
    index90  
       2019-05-27 19:25:40 +08:00
    CAS 方案的为什么会存在 cookie 跨域获取问题?不对,CAS 方案为什么要跨域获取 cookie ?
    kekxv
        14
    kekxv  
       2019-05-27 19:27:01 +08:00 via Android   ❤️ 1
    有已知远端:
    已知远端开放获取 token 的接口,开放跨域
    然后你知道怎么做了
    无已知远端但局域网:试试 IP ???
    index90
        15
    index90  
       2019-05-27 19:31:15 +08:00   ❤️ 1
    1. 访问 A 站点,如果有登录态,正常登陆
    2. 如果没有登录态,跳转到 SSO 站点登录页,query 带 A 站点回调地址(这时候是 SSO 的站点了)
    3. SSO 站点登录页判断是否有 SSO 站点的登录态,如果有,调用 A 站点回调地址,query 带 token。如果没有就输入用户名密码,登录 SSO 站点成功,调用 A 站点回调地址,query 带 token。
    4. A 站点回调地址,获取 query 中的 token,后台访问 SSO 站点的 token 验证接口
    5. 验证成功,A 站点后台设置 session,记录 SSO 站点提供的用户信息。

    你确定你看懂了 CAS ?
    sherryqueen
        16
    sherryqueen  
       2019-05-27 19:46:14 +08:00
    重定向到 sso 登录页面 进行登录. 在后端进行登录校验. 登录了就前往目标页面并种 cookie 否则跳转登录页
    Canon1014
        17
    Canon1014  
    OP
       2019-05-27 19:48:46 +08:00
    @zsc8917zsc #8 感谢,测试过是没问题的,算是一个保底的方案了
    Canon1014
        18
    Canon1014  
    OP
       2019-05-27 19:50:30 +08:00
    @index90 #15
    @sherryqueen #16
    @wangxiaoaer #3
    感谢三位老哥,我好像对 CAS 有点误解 现在理解多了,准备重新弄下了
    Canon1014
        19
    Canon1014  
    OP
       2019-05-27 19:53:31 +08:00
    @wunonglin #11 可是 redis 存了一堆 token 怎么知道哪一条是当前用户的 XD
    ZaytonHoneycutt
        20
    ZaytonHoneycutt  
       2019-05-27 21:11:16 +08:00 via iPhone   ❤️ 1
    @Canon1014 需要一个 hash 保存用户 id 到当前 session key 的映射
    wunonglin
        21
    wunonglin  
       2019-05-27 21:23:51 +08:00   ❤️ 1
    @Canon1014 那我反过来问,当前用户是怎么判断的,通过什么来判断执行这个操作的是“用户”,那肯定是请求者的 header 里带 auth 字段嘛,值就是 token 咯,后台接收到了,再去 redis 取 redis.get('token:MKSMKASMKAM'),返回用户 uid,这不就好咯。。如果返回 null 那就是非法 token,返回 403 就 ok 咯
    zwh2698
        22
    zwh2698  
       2019-05-28 07:03:33 +08:00 via Android
    其实我没明白为啥是前端直接请求,不是后端做的吗?前端页面就只要问自己所在的后端就可以了
    Canon1014
        23
    Canon1014  
    OP
       2019-05-28 08:16:11 +08:00
    @wunonglin #21
    @ZaytonHoneycutt #20
    好像了解了,抽空实践下试试,感谢
    EricInBj
        24
    EricInBj  
       2019-05-28 09:13:09 +08:00   ❤️ 1
    你真的看过了 CAS 吗? 这个跟 IP 还是域名访问没关系。。。
    luw2007
        25
    luw2007  
       2019-05-28 11:18:14 +08:00
    @EasyProgramming
    JWT 如果只用来验证登录,是不需要存储的。都是通过相同的密钥加密生成的。
    luw2007
        26
    luw2007  
       2019-05-28 11:19:34 +08:00
    可以看看 https://jwt.io/ 。两个系统同时使用相同的密钥可能存在风险。 不过都是 web 应用,可以随时切换到新的密钥上。
    jaylee77
        27
    jaylee77  
       2019-05-28 11:31:36 +08:00
    @wunonglin 你先搞明白什么叫单点登入
    Canon1014
        28
    Canon1014  
    OP
       2019-05-28 12:08:27 +08:00
    @EricInBj #24 我开始理解错了
    ivydom
        29
    ivydom  
       2019-10-10 16:37:31 +08:00
    用 authing 可以快速实现单点登录,快速体验地址:sample*authing*cn,把 * 换成 . 即可
    Shikyou
        30
    Shikyou  
       2020-06-24 16:59:51 +08:00
    这一类实现单点登录的用户管理的云服务已经很多了,为什么还要自行开发呢?
    比如楼上说的国内的 Authing,还有美国的 Auth0 和 AWS Cognito 都行的(国内由于政策原因用不了)。
    用了以后就回不去了,再也无需开发、运维用户系统
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1111 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 19:45 · PVG 03:45 · LAX 11:45 · JFK 14:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.