Я использую аутентификацию пользователя Django с PHP.Будет ли эта схема аутентификации на основе файлов cookie безопасна? - PullRequest
3 голосов
/ 28 января 2011

У меня есть сайт, написанный на PHP, и я добавляю новые функции, используя Python и Django. Частью этого будет аутентификация Django с использованием стандартного пакета contribs.auth.

Когда кто-то вошел в систему, используя нашу настройку Django, когда он перейдет на сторону PHP, мне нужно убедиться, что он вошел в систему и использует информацию пользователя из базы данных).

Каков наилучший способ получения идентификатора пользователя и доказательства того, что идентификатор сеанса Django действителен из PHP, с использованием этого значения cookie сеанса Django?

Мой план заключается в создании хеш-кода идентификатора сеанса Django, моего секретного ключа Django и идентификатора пользователя при входе в систему. Это значение будет установлено как дополнительный файл cookie. Затем в PHP я извлекаю идентификатор пользователя, создаю его хеш и секретный ключ плюс значение cookie сеанса Django, и сравниваю, если они совпадают.

Я расширил представление авторизации при входе в систему, чтобы установить дополнительный файл cookie после успешной аутентификации пользователя. Вместо HttpResponseRedirect он возвращает HttpResponseSetAuthCookieAndRedirect.

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, который является хешем идентификатора сеанса, моего секретного ключа Django и идентифицированного идентификатора пользователя, который совпадает с идентификатором сеанса.

В 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

Пока это работает.

Звучит ли эта идея?

Ответы [ 2 ]

3 голосов
/ 28 января 2011

Если вы можете распаковать в PHP то, что Django протолкнул в сеанс, то вы можете просто получить соответствующие данные сеанса непосредственно из базы данных (используя идентификатор сеанса из cookie), и тогда вы получите прямую информацию о том, какой пользователь вошел в систему. Сайт Django - если есть.

EDIT:

Вот "шифрование", которое использует 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',
}

- плюс, конечно, другие данные сеанса, которые вы сами задали

0 голосов
/ 28 января 2011

Знаете ли вы, возможно ли создать решение, которое работает наоборот, то есть позволяет войти в приложение PHP и использовать эту информацию для входа в приложение Django без необходимости вводить имя пользователя / пароль снова?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...