【问题标题】:I'm using Django user authentication with PHP. Will this cookie based authentication scheme be secure?我正在使用带有 PHP 的 Django 用户身份验证。这种基于 cookie 的身份验证方案是否安全?
【发布时间】:2011-06-17 04:41:23
【问题描述】:

我有一个用 PHP 编写的网站,并且正在使用 Python 和 Django 添加新功能。其中一部分将是使用标准 contribs.auth 包进行 Django 身份验证。

一旦有人使用我们的 Django 设置登录,当他们来到 PHP 端时,我需要查看他们是否已登录并使用数据库中的用户信息)。

使用此 Django sessionid cookie 值从 PHP 获取用户 ID 并证明 Django 会话 ID 有效的最佳方法是什么?

我的计划是在登录时对 Django 会话 ID、我的 Django 密钥和用户 ID 进行哈希处理。该值将设置为附加 cookie。然后在 PHP 中,我将提取用户 id,对其和密钥加上 Django sessionid cookie 值进行哈希处理,然后比较它们是否匹配。

我扩展了身份验证登录视图,以便在用户成功通过身份验证后设置一个额外的 cookie。它将返回 HttpResponseSetAuthCookieAndRedirect,而不是 HttpResponseRedirect。

HttpResponseSetAuthCookieAndRedirect 获取 request.session.session_id 和 user_id 作为参数。

class HttpResponseSetAuthCookieAndRedirect(HttpResponse):
    """ a cookie enhanced version of HttpResponseRedirect """
    status_code = 302

    def __init__(self, user_id, session_id, redirect_to):
        HttpResponse.__init__(self)
        self['Location'] = iri_to_uri(redirect_to)

        my_hash=hashlib.sha512('{0}|-|{1}|-|{2}'.format(settings.SECRET_KEY,user_id,session_id)).hexdigest()

        cookie_hash="{0}::{1}".format(user_id,my_hash[:64])

        self.set_cookie('check', value=cookie_hash, max_age=172800, path='/', domain=None)

这会设置一个 cookie,它是会话 ID、我的 Django 密钥以及与会话 ID 匹配的经过身份验证的用户 ID 的哈希值。

在 PHP 中,

$check_cookie=$_COOKIE['check'];
$django_cookie=$_COOKIE['sessionid'];

$check_cookie=str_replace('"','',$check_cookie);
$django_cookie=str_replace('"','',$django_cookie); //they have quotes for some reason

$parts=explode('::',$check_cookie);

$sent_user_id=(int)$parts[0];
$sent_hash=$parts[1];

$cookie_hash=hash('sha512',"$secret_key|-|$sent_user_id|-|$dj_cookie_sessionid");
$reconstructed_security_hash=$sent_user_id.'::'.substr($cookie_hash,0,64);

if($reconstructed_security_hash==$cookie_hash)
  {
  return $sent_user_id; //cookies are valid, and user id is the one set by Django for this session id.
  }

return false; //cookies do not match

到目前为止,这是有效的。

这个想法合理吗?

【问题讨论】:

  • 顺便说一下,我对 Django 还很陌生,所以如果有更好的方法来做到这一点(比如通过 sessionid 值查找存储在数据库中的会话),我愿意接受建议.

标签: php python django authentication cookies


【解决方案1】:

如果您可以在 PHP 中取消 Django 在会话中腌制的内容,那么您可以直接从数据库中获取相关的会话数据(使用 cookie 中的会话 id),然后您将获得哪个用户登录的直接信息Django 站点 - 如果有的话。

编辑:

这是 Django 使用的“加密”:

http://code.djangoproject.com/browser/django/tags/releases/1.2.4/django/contrib/sessions/backends/base.py#L86

“解密”后你应该得到类似的东西:

{
    '_auth_user_id': 123,
    '_auth_user_backend': 'django.contrib.auth.backends.ModelBackend',
}

--当然还有你自己设置的其他会话数据

【讨论】:

  • 听起来不错,然后我可以使用会话存储,这可能也会减少工作量。你知道会话数据是否只是腌制的吗?看起来它也是 Base64 编码的。 Django 文档说会话数据是“加密的”...
  • 看看我上面添加的链接。
  • 感谢您的信息。似乎访问会话数据是最好的主意。
【解决方案2】:

你知道是否有可能构建一个相反的解决方案,即,它可以登录 PHP 应用程序并使用此登录信息登录 Django 应用程序,而无需输入用户名/又要密码了吗?

【讨论】:

  • 我实际上使用了我的 asnwer 中的方法从一个站点登录到另一个基于 Django 的站点。所以是的,这绝对是可能的。
  • “你真的应该把这个作为它自己的问题发布 (...)”@Cole 好的,很抱歉把我的问题发布在错误的地方。
  • 是:请参阅此问题。 stackoverflow.com/questions/5023762/…
猜你喜欢
  • 2013-01-20
  • 2016-03-24
  • 2018-07-03
  • 2017-02-23
  • 2016-12-18
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
相关资源
最近更新 更多