2009-07-19 113 views
2

我正在django中构建一个小应用程序作为服务,现在是将它集成到某些客户端PHP web应用程序的时候了。Django单点登录和Php站点:跨域登录?

我们的客户来自域名www.a.com的为他的用户处理他自己的身份验证,并可能使用cookie进行会话。

我怎么能让他的域名登录用户也登录在我的Django应用dommain www.b.com/clientA/?

我明白我如何让他们在我的域名上重新登录,并使用域名A的authbackend检查凭证,但这意味着用户必须输入他的登录名/密码两次:www.a.com和www.b. COM。

从域名www.a.com访问cookie是不可能的,因为我认为安全的原因。

你将如何处理?

+0

是否正在修改PHP应用程序? – oggy 2009-07-19 21:55:07

+2

顺便说一句,正确的术语是“Djangonauts” – 2009-07-21 13:12:44

回答

7

您无法访问来自其他域的Cookie,这是正确的。但是,如果它位于子域中,则应该能够访问Cookie,如果它们设置正确的话。

如果你绝对必须在完全独立的域上拥有它们,这将会有点棘手。如果你不能修改现有的PHP代码,你几乎可以忘记它。

一种选择是使用OpenID--这可能是最简单的方法来解决这个问题,因为有PHP和Python可用的OpenID库。 OpenID将允许你在认证方面有一个单一的标志,并且由于它已经在各种网站上使用,它已经被证明和有效。

另一种选择是编写自定义单一登录系统。

其基本思想是,当用户到达您的网站时,您将他们引导至登录网站。这可以在PHP或Python结尾,也可以分开。在这里,用户将登录,然后登录会生成一个密钥 - 这可以是散列,随机字符串,只要它不可预测 - 并且用户通过密钥重定向回主站点。

然后主站点看到用户有一个密钥,并向后台的登录站点发送请求以验证用户的密钥。

现在用户在一个站点上登录。当用户访问第二个站点时,它也会将用户重定向到登录站点。由于用户已经登录,登录站点只需用新密钥重定向用户,第二个站点从登录站点验证它,现在用户已登录,而无需再次输入其凭据。

1

您可以来回使用HTTP重定向。当用户访问www.b.com并且没有设置cookie时,重定向到www.a.com/crosslogin?return_to=URL&challenge=stuff。在a.com上,检查cookie,如果已设置,则重定向到URL?verified=otherstuff

如果您希望用户防止伪造身份验证,则需要质询 - 响应加密。 a.com和b.com需要设置一个共享密钥,并且用秘密加密。其他人也用这个秘密加密;当解密时,它会给出一个元组(东西,用户)。 b.com可能需要保留重播缓存以确保其他用户只能使用一次。

0

我看到如下选项:

1)使用开放ID为贾尼Hartkainen建议。这可能是最好的解决方案。

2)通过使用HTTP反向代理一个域名:

使用反向HTTP代理把两个PHP应用程序,并在同一个域的Django应用程序。这会让你访问你的PHP应用程序的会话cookie。

一旦你在你的Django应用程序中的PHP会话ID运行设置检查是谁登录会话cookie的PHP应用程序的请求。 不幸的是,这可能需要HTML刮或实施在PHP应用程序中的简单的服务,会返回登录用户的名称。 一旦你获得登录的用户,你可以在你的django应用中授权它。

3)通过GET传递PHP会话ID:

修改的PHP应用程序添加的会话ID作为参数传递给链接到您的Django应用程序。 例如要求客户参考您的网站如下:

<yourwebsite.com>/?client_session_id=<session_id>&client_name=<client_name> 

一旦你的会话ID,你可以在点描述2.

6

好的验证用户,这是怎么验证一个Django来自PHP的用户,或者如何从PHP读取Django密码。

我认为OpenID是最好的解决办法,但我不得不在PHP应用程序Django的用户进行身份验证当今共享同一个数据库,这是我如何解决:

<?php 

/* Generates crypted hash the same way as Django does */ 
function get_hexdigest($algorithm, $salt, $raw_password) { 
    if (!array_in($algorithm, array('md5', 'sha1'))) { 
     return false; 
    } 
    return $algorithm($salt.$raw_password); 
} 

/* Checks if password matches the same way Django does */ 
function check_password($raw_password, $django_password) { 
    list($algorithm, $salt, $hsh) = explode('$', $django_password); 
    return get_hexdigest($algoritm, $salt, $raw_password) === $hsh; 
} 

?> 

的关键是理解的格式,其中Django的保存密码,这就是:

[算法] $ [盐] $ [散列]

因此,例如我有AUTH_USER行中的“管理员”,密码为“admin”用户和密码字段是:

sha1$63a11$85a93f217a72212b23fb0d5b95f3856db9575c1a 

该算法为“sha1”,随机生成的盐为“63a11”,加密哈希为“85a93f217a72212b23fb0d5b95f3856db9575c1a”。

那么,你是谁在PHP中产生加密哈希?您简单的串联盐和原始密码,并用散列算法它,在这种情况下,SHA1:

<?php 

$salt = '63a11'; 
$pass = 'admin'; 

echo sha1($salt.$admin); // prints "85a93f217a72212b23fb0d5b95f3856db9575c1a" 

?> 

这是不难!我通过阅读Django源代码中的相关代码得到了它。