Шифрование и дешифрование в Джанго - PullRequest
0 голосов
/ 01 июля 2018

Я работаю над внедрением ссылки отказа от подписки в моих электронных письмах. Я веду таблицу для неподписанных пользователей.

Я хочу знать адрес электронной почты, как только пользователь нажмет на ссылку отказа от подписки. Конечно, я не могу отправить его как параметр get, так как его можно легко изменить.

A например. Ситуация такова: я хочу отправлять электронные письма 10 моим друзьям, и каждое электронное письмо является HTML-письмом и имеет URL-адрес для отказа от подписки, поэтому, если пользователь нажимает на ссылку, он добавляется в мою модель UnsubscribedUser, а затем я не отправлять им электронные письма.

Я хочу каким-то образом зашифровать адрес электронной почты, передать его в качестве параметра get, а затем расшифровать его в представлении и сохранить в моей базе данных. Я не знаю, как мне поступить в Джанго. Если есть какой-то лучший способ реализовать это, пожалуйста, дайте мне знать.

1 Ответ

0 голосов
/ 01 июля 2018

Как правило, шифрование также не является хорошей идеей, поскольку, если ключ дешифрования становится известным, люди могут дешифровать весь возможный контент, кроме того, было бы также довольно легко начать взламывать это приложение с помощью ключа шифрования: если я как-нибудь узнаю ключ шифрования, я могу создать URL, например, чтобы сбросить пароль произвольного адреса электронной почты, и, таким образом, сбросить пароль Боба и войти в систему как Боб позже.

Типичным решением для этого является создание таблицы «сеансов отмены подписки». Если кто-то просит отписаться, вы добавляете этого человека в таблицу и добавляете в нее что-то вроде random id. Лучше , а не использовать такие вещи, как первичный ключ, так как предсказуемо, каким будет предыдущий и следующий id с, и тогда люди могут «взломать» эту систему, чтобы подтвердить отмену подписки другого человека. .

Таким образом, мы создаем таблицу, например, с GUID (глобально уникальным идентификатором):

from datetime import datetime, timedelta
from django.conf import settings
from django.db.models import CASCADE, DateTimeField, ForeignKey, Model, UUIDField
from uuid import uuid4

def tomorrow():
    return datetime.now() + timedelta(days=1)

class UnsubscribingUser(Model):
    uuid = UUIDField(default=uuid4, editable=False, unique=True)
    user = ForeignKey(settings.AUTH_USER_MODEL, on_delete=CASCADE)
    expires = DateTimeField(default=tomorrow)

Так что теперь, если вы хотите отписать кого-то, вы можете создать такой UnsubscribingUser экземпляр модели и отправить электронное письмо со ссылкой:

def unsubscribe(request):
    uu = UnsubscribingUser.objects.create(user=request.user)

    # send mail with uu.uuid
    # ...
    pass

В этом электронном письме должен быть указан URL, который ссылается на представление, обрабатывающее UUID:

from datetime import datetime
from django.http import Http404

def unsubscribe_url(request, uuid):
    uu = get_object_or_404(UnsubScribingUser, uuid=uuid)
    if uu.expires <= datetime.now():
        # unsubscribe logic
        # ...
        uu.delete()
    else:
        # too late
        # do something in that case, for example
        uu.delete()
        raise Http404

Таким образом, мы сначала проверяем, существует ли такой экземпляр модели UnsubscribingUser, в этом случае мы проверяем, истек ли уже «сеанс». Если нет, то мы отписываемся.

Таким образом, электронное письмо содержит URL reverse(unsubscribe_url, uuid=uu.uid). Истечение срока действия обычно желательно, так как в противном случае в таблице будет храниться огромное количество UUID, и после белого становится более вероятным, что ввод случайного UUID может отменить подписку случайного человека.

...