使用JSONP和cookie进行跨域登录

and*_*ber 10 authentication cookies jsonp login cross-domain

如何让用户登录到一个域并自动登录到我的其他域,而无需在每个域上提交表单?

and*_*ber 16

我们都知道cookie不可跨域访问,因为这会带来安全风险.但是,使用一些技巧,有办法解决这个问题.基本上我们在中央域上为用户设置cookie,使用脚本检查该cookie的存在,然后使用JSON-P回调将该cookie复制到其他域.更详细:

在登录

步骤1

<form>上显示mydomain.com(或myotherdomain.com等)应POST到central.com/login

第2步

打开central.com/login,验证用户名和密码,并在central.com域上设置包含该用户唯一值的cookie .然后将用户重定向回mydomain.com

SELECT unique_value FROM users WHERE username = $username
set cookie on central.com containing unique_value
Run Code Online (Sandbox Code Playgroud)

第3步

回到mydomain.com我们嵌入了一个javascript调用central.com/check.

<script type="text/javascript" src="http://central.com/check"></script>
Run Code Online (Sandbox Code Playgroud)

第4步

central.com/check我们检查的唯一的Cookie设置为用户.然后我们嵌入了一个JavaScript回调(JSON-P),通知mydomain.com用户已登录.没有包含敏感的用户数据,否则hacker.com可以嵌入此脚本并获取用户的信息.(将适当的Access-Control标头设置为仅允许经过验证的域可以减轻此风险.)相反,我们会根据时间戳创建一次性哈希,以便mydomain.com验证身份验证.

if cookie on central.com is valid
    user_data = array(
       'success' => true,
       'uid'     => $uid,
       'time'    => time_stamp,
       'hash'    => disposable_salted_hash( $uid, time_stamp )
    )
    echo 'setDomainCookie(' . json_encode(user_data) . ')'
Run Code Online (Sandbox Code Playgroud)

第5步

然后执行回调函数,设置cookie mydomain.com.最后,我们可以刷新页面或仅使用他们登录的JavaScript(最好是两者)提醒用户.

function setDomainCookie( user_data ) {
    if( user_data.success ) {
        $.post('/setcookie', user_data, function() {
            location.reload(true);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

mydomain.com/setcookie类似于第2步.当然这假设两个站点都可以访问相同的数据库(和代码)

if hash = disposable_salted_hash( $uid, time_stamp )
    SELECT unique_value FROM users WHERE uid = $uid
    set cookie on mydomain.com containing unique_value
Run Code Online (Sandbox Code Playgroud)

第6步

用户下次刷新页面时,我们可以绕过JSON-P回调

if cookie on mydomain.com is valid
    loggedin = true
else
    delete cookie on mydomain.com
    proceed to Step 3
Run Code Online (Sandbox Code Playgroud)

注销

第7步

mydomain.com应该去的链接central.com/logout

第8步

central.com/logout,不仅删除了cookie,而且重置了该用户的唯一值.用户被重定向回mydomain.com

delete cookie on central.com
UPDATE users SET unique_value = new_random_value() WHERE username = $username
Run Code Online (Sandbox Code Playgroud)

第9步

现在重置了唯一值,从上面的步骤6失败,cookie也被删除mydomain.com,并且用户被有效地注销.

笔记

  1. 至关重要的是,central.com/check步骤4开始设置正确的标头,以便它不被缓存.

  2. 用户登录时的步骤3-5可能会导致轻微延迟.刷新显示他们登录的某种JavaScript警报是明智的.对于步骤3中的脚本尽可能接近页面顶部也很重要.

  3. 步骤5中,您可以选择在每个域上存储唯一的cookie值.

  4. 单独的central.com域名并不是必需的; 如果您愿意,您可以使用其他域之一作为中心域.该域的逻辑显然会有所不同.

  5. 要使其在Internet Explorer上运行,您需要在cookie上附加P3P策略.

  6. 正如IvanGusev在评论中指出的那样,这种方法的一个缺陷是,如果用户退出设备A,它也会将其记录在每个其他设备之外.

  7. 希望这对人们有所帮助.我非常有兴趣收到反馈,特别是如果这种方法存在任何安全漏洞.我认为黑客可以做的最糟糕的事情就是重复步骤3-5并在mydomain.com你不知情的情况下登录,但那将是无害的.

  • 很好的答案.但是,我也想知道使用这种方法是否存在任何安全漏洞.希望有人比我更有经验... (4认同)