首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Coding
V2EX  ›  问与答

关于单点登录,在一些特定条件下,有没有相对简洁而又有效的实现方式?

  •  
  •   revlis7 · 2013-08-06 22:54:43 +08:00 · 2851 次点击
    这是一个创建于 2318 天前的主题,其中的信息可能已经有所发展或是发生改变。
    据我自己平时了解到的情况,关于单点登录,可以有若干种做法

    自己遇到的情形一般是,公司已经有了一个站点A,后来又多了一个站点B,但是运行在不同的域名下(关键),需要用户访问A的同时,能够自动登录站点B(不需要用户有一个额外授权认证的过程)

    如果你google的话,通常会搜到用CAS做单点登录,可是CAS首先需要JAVA环境,其次CAS的做法好像和Oauth类似(可能就是衍生出来的概念,自己没有实际用过CAS),感觉如果只是要让自己两个站点同时登录,搞一套CAS什么的未免有点小题大作,另外OpenID什么的也了解过,也有类似的疑问。

    说说我以前自己的做法:

    1、用户请求站点B
    2、跳转至站点A判断用户登录状态
    3、如果已经登录跳转回站点B,并带上加密过的用户信息
    4、站点B解密信息,设置站点B的登录状态,完成登录

    另外还了解到一种做法:

    1、用户请求站点B
    2、站点B的页面中,包含一段访问站点A某个API的请求
    3、这个站点A的API返回的是站点A下的cookie信息,并转换成JS嵌入站点B的页面
    4、B站点页面获取到站点A的cookie后,后面的也不用多说了吧

    我想知道我提到的这几种实现,究竟各自有什么样的优势或者劣势,或者还有其它更好的实现方式?在目前这种情况下,是否有足够的理由去使用CAS、Oauth或OpenID等类似的方式?
    10 回复  |  直到 2019-10-10 16:39:26 +08:00
        1
    revlis7   2013-08-07 11:52:29 +08:00
    Any Ideas?
        2
    wingoo   2013-08-07 12:06:59 +08:00   ♥ 1
    可以看下oauth 的实现, 如果自己跳转搞的话, 建议不要带用户信息, 可以一个guid过去,一次失效, 判断是否登录
        3
    atan   2013-08-07 12:26:38 +08:00   ♥ 1
    如果是apache的话可以试试mod_auth_tkt
        4
    revlis7   2013-08-07 12:54:57 +08:00
    @atan 貌似又多了个选择,回头了解一下

    @wingoo Oauth当然可以做,但问题就是,虽然Oauth可以用来做站点登陆这件事,但是实际上Oauth本身解决的是信息授权这个问题,登录只是授权认证其中的一部分而已。而且Oauth登录一般都是与第三方站点合作才会使用,那如果两个站点本身都是自己的,何必还需要一个认证授权的过程。
        5
    revlis7   2013-08-07 12:57:03 +08:00
    这些都是我自己的理解,如果有错误的地方,可以纠正我。
        6
    wingoo   2013-08-07 13:06:05 +08:00
    @revlis7 oauth只能说是曲线实现统一登录, 但公开的方案好处是安全之类的都考虑到了, 自己做套方案的话, 不能保证想全了
        7
    denger   2013-08-07 13:11:42 +08:00   ♥ 1
    可以看看我之前写的这方面的文章:
    http://denger.iteye.com/category/161641

    个人对 cas 比较熟悉。同样是基于统一认证中心来规避 session/cookie 存储跨应或域的问题。使用也较为简单,虽然它的 认证中心是基于 Java 实现,但是对于客户端(应用程序) 来说,提供有各种语言实现。python /php 等~

    oauth 之类的个人感觉它更适用于第三方网站的登录授权。
        8
    ksc010   2013-08-07 13:22:31 +08:00
    我现在用的是第二种
        9
    atan   2013-08-07 13:46:29 +08:00
    @revlis7 CAS相对太庞大了些, 感觉有些时候小项目背后拉了个大家伙, mod_auth_tkt相比轻巧很多, 而且部署和迁移都挺方便的
        10
    ivydom   62 天前
    最简洁的就是用 Authing,超简单就可以实现:

    ``` javascript
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Authing 单点登录实现示例</title>
    <style>
    body {
    font-family: Avenir,Helvetica,Arial,sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
    }

    a {
    color: #42b983;
    cursor: pointer;
    text-decoration: underline;
    }
    </style>
    </head>
    <body>
    <div style="margin-bottom:22px">
    <img data-v-1129b33e="" alt="Vue logo" height="200" src="https://cdn.authing.cn/[email protected]">
    <h1>使用 Authing 五分钟实现单点登录</h1>
    <h2>当前状态:<span id="status">检测中</span></h2>
    <h3 id="track-session-tip" style="display:none">以下是你的 session 信息:</h3>
    <pre style="text-align: left;" id="session"></pre>
    </div>
    <a id="btn-login">登录</a>
    <a id="btn-logout">退出</a>
    <p>
    <a href="https://authing.cn/login" target="_blank">使用 Authing</a>
    <a href="https://github.com/Authing/web-sso-sample" target="_blank" style="margin-left:11px">本示例代码</a>
    <a href="https://docs.authing.cn/authing/quickstart/implement-sso-with-authing" target="_blank" style="margin-left:11px">开发文档</a>
    </p>
    <p>
    <a href="https://github.com/Authing/oidc-window">在单窗口中打开登录页面的代码示例</a>
    </p>
    <script src="https://cdn.jsdelivr.net/npm/@authing/sso/dist/AuthingSSO.umd.min.js"></script>
    <script src="https://cdn.authing.cn/js-beautify/1.7.5/beautify.min.js"></script>
    <script>
    const authing = new AuthingSSO({
    appId: "5d70d0e991fdd597019df70d", // OIDC 应用的 ID
    appType: "oidc", // SSO 类型为 OIDC 类型
    appDomain: "sample-sso.authing.cn"
    });

    const callTrackSession = async function() {
    const res = await authing.trackSession();
    if (!res.session) {
    status.innerHTML = '未登录';
    logout.setAttribute('style', 'display:none');
    }else {
    status.innerHTML = `${res.userInfo.username || res.userInfo.email || res.userInfo.nickname} 你好,你已处于登录状态`;
    login.setAttribute('style', 'display:none');
    sessionTip.setAttribute('style', 'display: block');
    sessionPre.innerHTML = js_beautify(JSON.stringify(res));
    }
    };

    // 检查登录状态
    callTrackSession()

    const login = document.getElementById('btn-login');
    const logout = document.getElementById('btn-logout');
    const status = document.getElementById('status');
    const sessionPre = document.getElementById('session');
    const sessionTip = document.getElementById('track-session-tip');

    login.onclick = function() {
    authing.login();
    };

    logout.onclick = async function() {
    let res = await authing.logout();
    alert(JSON.stringify(res));
    location.reload();
    };
    </script>
    </body>
    </html>
    ```
    线上体验:sample.authing.cn

    https://github.com/Authing/web-sso-sample/blob/master/index.html
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4305 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 32ms · UTC 02:56 · PVG 10:56 · LAX 18:56 · JFK 21:56
    ♥ Do have faith in what you're doing.