在Django中加密和解密

时间:2018-07-01 13:15:39

标签: django encryption unsubscribe

我正在努力在电子邮件中实现“取消订阅链接”。我正在为退订用户维护一张表。

一旦用户单击退订链接,我想知道电子​​邮件地址。当然,我不能将它作为get参数发送,因为可以很容易地对其进行修改。

例如情况是-我想向10个朋友发送电子邮件,每个电子邮件都是HTML电子邮件,并且具有取消订阅的URL,因此,如果用户单击链接,则他将被添加到我的UnsubscribedUser模型中,然后我不要向他们发送电子邮件。

我想以某种方式加密电子邮件地址,将其作为get参数传递,然后在视图中解密,并将其存储在我的数据库中。 我不知道该如何在Django中进行此操作。 如果有更好的方法可以实现这一点,请告诉我。

1 个答案:

答案 0 :(得分:1)

通常,加密也不是一个好主意,因为如果知道解密密钥,人们就可以解密所有可能的内容,此外,使用加密密钥开始对这个应用程序进行黑客攻击也相当容易:如果我以某种方式发现作为加密密钥,我可以构造一个URL以例如重置任意电子邮件地址的密码,从而重置Bob的密码,然后稍后以Bob身份登录。

典型的解决方案是构造“退订会话”表。万一有人要求退订,您可以将该人添加到表格中,并在其中添加某种 random id。最好不要使用主键之类的东西,因为可以预测前id和后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) 的含义,然后人们可以“入侵”该系统以确认取消订阅另一个人。

因此,我们创建一个表,其中包含一个GUID(全局唯一标识符):

UnsubscribingUser

因此,如果您现在想要退订某人,则可以构造这样的def unsubscribe(request): uu = UnsubscribingUser.objects.create(user=request.user) # send mail with uu.uuid # ... pass 模型实例,并发送带有链接的电子邮件:

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

然后,电子邮件中应包含一个URL,该URL链接到处理UUID的视图:

UnsubscribingUser

因此,我们首先检查是否存在这样的reverse(unsubscribe_url, uuid=uu.uid)模型实例,在这种情况下,我们检查“会话”是否已经过期。如果没有,我们将退订。

因此,电子邮件包含graph_test URL。到期通常是理想的,因为否则最终该表将存储大量UUID,并且在输入白色后,输入随机UUID 取消订阅随机人的可能性就更大。