安全和灵活的跨域会议(Secure and Flexible Cross-Domain Sessio

2019-06-21 22:07发布

我有,我希望你能获得帮助的问题。 比方说,我的一个假设一家名为“Blammo”的工作,我们有一个名为“登录”假设产品。 我试图建立一个系统,如果有人可以登录到logfromblammo.com和订购我们的一些产品,然后当他们准备购买去checkout.blammo.com来支付他们的订单。 最后,我想允许Blammo推出一个新产品的假设与它自己的网站:rockfromblammo.com,并让该网站也能分享checkout.blammo.com一个会话,以便用户可以在这两个产品单一的购物车网站。

当然上述假设的情况是不是我公司的实际工作原理,但它是什么,我需要做一个公平的例子。 我们现有的用户数据库,我们有办法来验证我们的任何关于我们的任何网站的用户,但我的目标是让用户从一个网站到另一个无缝跨越,而无需重新验证。 这也将使得我们能够无缝地传输数据,如购物车,结账网站。

我有(简述)望着解决方案例如OpenID,但我需要能够整合,我们有什么解决方案与我们现有的认证方法,它是不是非常强劲。 有没有通过PHP独自做到这一点没有什么好的办法?

Answer 1:

你可以做的是建立网站的过载会话之间的“交叉”的链接。

最简单的方法是通过查询字符串传递会话ID; 例如

http://whateverblammo.com/?sessid=XXYYZZ

在你开始想,任何人都可以捕获该信息,想想你的cookies如何转移; 你没有使用SSL假设,有没有人谁水龙头网络太大的区别。

这并不意味着它是安全的; 一,用户可能会意外地复制/粘贴地址栏,从而泄露了他们的会议。 为了限制这种暴露,你可以立即重定向到一个页面,而会话ID收到后。

请注意,使用mcrypt()上的会话ID也不会有多大效果,因为它不是这就是问题所在值的知名度; 会话劫持并不关心底层价值,只有它的URL的重现性。

你必须确保ID只能使用一次; 这可以通过创建跟踪使用计数的会话变量来实现:

$_SESSION['extids'] = array();

$ext = md5(uniqid(mt_rand(), true)); // just a semi random diddy
$_SESSION['extids'][$ext] = 1;

$link = 'http://othersite/?' . http_build_query('sessid' => session_id() . '-' . $ext);

当接收到:

list($sid, $ext) = explode('-', $_GET['sessid']);
session_id($sid);
session_start();
if (isset($_SESSION['extids'][$ext])) {
    // okay, make sure it can't be used again
    unset($_SESSION['extids'][$ext]);
}

你需要这些链接一个越过边界 ,因为会话可能得到自从上次再生。



Answer 2:

这是可以做到的,但不能用简单的饼干,这是不平凡的。 你是什​​么后跨越i.google.com,gmail.com,youtube.com等上(SSO)解决方案,单点登录,类似于谷歌的共享的登录的

我已经使用OpenID的过去来实现这一点。

其基本思想是有一个单一的身份验证域(供应商),每当网站(消费者)的人希望对用户进行认证,他们将其重定向到身份验证域。 如果他们没有登录,就可以登录使用的任何细节,你需要。

如果他们已经登录(甚至来自不同的目标网站),他们并不需要重新登录。

然后,用户通过添加URL中的令牌发送回目标站点。 此令牌用于在目标网站的服务器来验证用户进行身份验证与认证服务器。

这是一个非常简单的解释。 这样做并不困难,这样做安全是更加如此。 生成和认证令牌的细节牢固地是挑战性的部分。 这就是为什么我建议在建设一个精心设计的系统,例如OpenID。



Answer 3:

您需要设置会话cookie域,像这样:

session_set_cookie_params($lifetime,$path,'.site.com')

如果这个网站是在相同的域名,包括只会工作TLD (顶级域名)。

见这里获取更多信息

另外,如果你正在寻找在试图访问会话跨域,如从site1.netsite2.com ,那么这个不能做。



Answer 4:

在跨域Ajax的,你可能会发现该cookie,从动地,会话丢失了跨域请求。 如果你会作出从你们网站example.com到您的子s2.example.com Ajax调用,你需要在标题为PHP使用特性:

header('Access-Control-Allow-Origin: https://example.com');
header('Access-Control-Allow-Credentials: true');

在JS,你要添加

xhrFields: { withCredentials: true }

否则,Cookie不会通过,你不能使用会话的子网域上。

全JS请求子域将不丢失会话

$.ajax({
    url: "https://s2.example.com/api.php?foo=1&bar=2",
    xhrFields: { withCredentials: true },
    success:function(e){
        jsn=$.parseJSON(e);
        if(jsn.status=="success") { 
                alert('OK!');
        } else {
                alert('Error!');
        }
    }
}) 


Answer 5:

如果它是确定为您的网站依赖于JavaScript的功能,你大概可以做类似如下:

假设你有blammo.com一个会议,你想从rockblammo.com访问它。 在rockblammo.com页面,你可以加载一个<script>blammo.com/get-session.js ,这将(从服务器端)返回会话ID。 一旦返回,你插入一个新<script>在页面标签,指着rockblammo.com/set-session.js?sessionId=XXX ,其中XXX为会话ID,你刚刚从blammo.com了。 现在,rockblammo.com的服务器端,会话cookie被更新,并设置该会话ID。 展望未来,两页,现在将共享相同的会话ID,并假设他们有机会获得在后台同一会话存储,他们将同步。

例如,从输出blammo.com/get-session.js将是:

var sessionId = "XXX";
var s = document.createElement("script");
s.src = "/set-session.js?sessionId=" + escape(sessionId);
document.body.appendChild(s);

从输出rockblammo.com/set-session.js将是空白的,但是将包括HTTP报头,如:

Set-Cookie: sessionId=XXX

如果你不喜欢依赖于JavaScript,你很可能被提出和在两个站点之间回重定向和传球的SessionID在查询字符串参数(GET PARAM)这样做。



文章来源: Secure and Flexible Cross-Domain Sessions