Fork me on GitHub

关于SSO(jsConnect)的一些发现和讨论。

edited 2013年08月08日 问答求助

这几天一直在研究 SSO的问题,于是发现论坛自带jsConnect插件,于是根据官方的文档了解了一下,由于不是特别懂英语所以看了大概,把内容呈上供大家一起研究。

SSO就是让外部程序的用户可以顺利登陆访问论坛的一种单点登陆技术。 官方有几篇文档但是我还是没看大明白,虽然已经可以实现基本的登陆。

根据文档1 ,说明了怎么开启论坛的sso登陆 和外部系统应该提供一个验证接口

http://vanillaforums.com/blog/jsconnect-technical-documentation/

技术文档jsConnect第1部分:站点级SSO

jsConnect使用javascript来允许跨域单点登录与其他站点。香草提供了单点登陆用来签名的库文件,可以根据自己的编程语言下载对应的jsConnect库文件来辅助验证。

然后文档介绍了 使用的通信加密方式 以及介绍了jsonp,这里我就不再赘述。

单点登陆使用了2个部分,1个是香草的jsConnect插件, 用来配置单点登陆的配置文件, 官方git上下载并启用后,可以创建站点。

里面有几个配置项:

clientid 唯一标示一个app的id

Secret 秘钥 用来加密通信

login url 登陆页面地址, 点击后将会跳转到 外部应用登陆。

reg url 注册页面地址, 点击后将会跳到外部应用注册。

authenticate url 认证页面地址, 这个会在论坛打开的时候 请求, 用来判断 外部应用是否登陆,这个也是最重要的。。

配置完 香草后 会有一个测试地址,不用管它。

然后在外部应用里创建 authenticate 方法。

这时候打开下载的外部库文件,库文件可以在这里下载

http://vanillaforums.com/blog/help/implementing-jsconnect-single-signon-on/#libraries

看下demo

// 1. 写入在香草里配置的 客户id 和秘钥

$clientID = "1234";

$secret = "1234";

$user = array();

//2 然后判断是否已经在外部系统里登陆

//islogin 是自己的函数 用来判断用户是否登陆

//如果登陆的话就写入

if(islogin()){

// 把用户uid,nicheng,电子邮件,头像信息写到数组里

$user['uniqueid'] = '123';

$user['name'] = 'John PHP';

$user['email'] = 'john.php@anonymous.com';

$user['photourl'] = '';

}

// 用WriteJsConnect把用户信息加密后生成通信数据,返回jsonp供 香草论坛调用

// 如果开启调试模式 $secure 可以给false,就不验证签名了,当然配置里必须也勾上允许调试

$secure = true;

WriteJsConnect($user, $_GET, $clientID, $secret, $secure);

//如果使用官方提供的库我不建议开启调试模式,应为生成签名的代码都写好了,不会出错,出错的话都是自己写的代码的问题。那么就可以写成如下方式,不要最后一个参数。

WriteJsConnect($user, $_GET, $clientID, $secret);

//这断代码写完后,请到香草后台 SSO配置页面 点击测试连接(这回用到它了),它回访问这个接口,用来检查通信结果是否正常。如果你代码没有报错能返回对用的jsonp数据,那么说说明通信已经成功。

这时候可以在 外部应用登陆前,点击论坛(别忘了开启只允许SSO插件登陆) 这时候 发现登陆和注册 都会跳转到之前在论坛里配置的登陆和注册地址。

ok

现在尝试在外部程序登陆,登陆后再点击论坛。 发现登陆、注册按钮都消失了, 登陆位置会显示你外部站点的 头像和昵称,并且出现一个按钮, 通过 XXXX 登陆。点击后弹出一个页面(有点像新浪微博的连接登陆的小窗) 稍后 小窗自动关闭,发现已经以外部账号的身份登陆了。。

当然还有一个例外。

如果你这个用户名和邮箱已经在论坛里登陆过了, 这时候点击 通过 XXXX 登陆 就不会自动登陆了,而是需要让你把论坛的账号和密码输入一次,用来关联身份。 下次再点通过 XXXX 登陆 就可以直接登陆上去了。而且连接登陆后的用户是找不到密码修改的页面的。

这时候我有几点疑问,就是我感觉这种方式并没有真正实现单点登陆,因为用户切到论坛页面还得手动点一次 通过 XXXX 登陆 ,才能登陆。

我觉得应该是在外部登陆成功后 主动通知到论坛,让论坛发送登陆cookie,但是我没在官方文档上看到相关说明,不知道有没有研究过香草SSO登陆的朋友们,能给一些合理的建议和解决方案。

谢过!

@chuck911

此话题使用的标签:

回复

  • 同时我也看了文档2

    jsConnect Technical Documentation Part 2: Embedded SSO with jsConnect

    嵌入式功能使用SSO技术

    这个文档我理解为,你要把他的评论功能引用在外部(比如友言评论这种),还能让这个引用的评论框实现登陆状态。

    看下它给的代码

    var vanilla_forum_url = 'http://your.url.com/'; //论坛地址 var vanilla_identifier = 'your-content-identifier'; // 评论页唯一标示 var vanilla_sso = 'SSO STRING'; // SSO 单点登陆认证字符串 加密过的 /*** 下面的请不要修改 ***/ (function() { var vanilla = document.createElement('script'); vanilla.type = 'text/javascript'; var timestamp = new Date().getTime(); vanilla.src = vanilla_forum_url + '/js/embed.js'; (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(vanilla); })();

    简单点说 就是 你增加一个 变量 vanilla_sso 这样 那个用户就能登陆了。

    其他文档说明就是怎么生成这个vanilla_sso 字符串了,不用管它,我从wordpress取到一段代码,自己稍加修改就可以使用。。PHP的 可以看一下。

    //生成sso string

    function get_sso_string() {

    $result = '';
    

    //如果登陆渠道用户数据,需要 uniqueid(通常是UID),email,name(通常是nickname)
    if(islogin()){

        $user = $db->find(array('uid'=>$this->uid),'','uid as uniqueid,email,nickname as name');
    
         $user = array('uniqueid'=>9,'email'=>'dome@email.com','name'=>'anythink');
    
        $clientID = '填入论坛SSO配置里的 站点id';
    
        $secret = '填入论坛SSO配置里的 密钥 Secret';
    
        if (!$clientID || !$secret)return '';
    

    //下面是加密签名用的代码可以无视

        $user['client_id'] = $clientID;
    
        $string = base64_encode(json_encode($user));
    
        $timestamp = time();
    
        $hash = hash_hmac('sha1', "$string $timestamp", $secret);
    
        $result = "$string $hash $timestamp hmacsha1";
    }
    
    return $result;
    

    }

    最后只要修改一下

    var vanilla_sso = '<?php echo get_sso_string();?>';

    这样嵌入的评论就可以识别单点登陆信息了。

    以上只是我YY,我没用过这个评论功能,所以以上是根据文档写的。

    一开始我还以为他可以给论坛发送登陆状态通知,后来发现我错了。

  • 路过,帮顶。

  • 我最近也在看这个登陆,你所说的
    这时候我有几点疑问,就是我感觉这种方式并没有真正实现单点登陆,因为用户切到论坛页面还得手动点一次 通过 XXXX 登陆 ,才能登陆。
    可以是用这个插件辅助实现:Vanilla jsConnect Auto SignIn 0.1.5b,http://vanillaforums.org/addon/jsconnectautosignin-plugin

  • edited 2013年08月09日 #4

    @anythink 我最近也在看这个登陆,你所说的

    这时候我有几点疑问,就是我感觉这种方式并没有真正实现单点登陆,因为用户切到论坛页面还得手动点一次 通过 XXXX 登陆 ,才能登陆。

    可以用下面这个这个辅助插件实现:Vanilla jsConnect Auto SignIn 0.1.5b,
    http://vanillaforums.org/addon/jsconnectautosignin-plugin

    编辑功能出错了?

  • @test 多谢~ 我去看一下!~

  • @test 测试结果是可以使用,但是有个bug,如果外部账号 在论坛已经存在,但未创建关系,会出现账号绑定页面,这时候页面就开始不停刷新了-。-

  • 有好多疑惑呀,我对php不熟悉用,了JSconnect之后,页面返回一串json的数据,香草那边也配置好了。要怎么实现登陆呢?你在上面提到要自己写一个WriteJsConnect($user, $_GET, $clientID, $secret);函数吗?以及在外部应用里创建 authenticate 方法?怎么写呢,,,,真心是菜鸟,求帮助,,,@anythink

  • edited 2014年09月14日 #8

    好像知道了--!@anythink

登录注册 才能回复。