Есть два способа, которыми я знаю, чтобы сделать это эффективно, поскольку в принципе нет способа помешать кому-либо подделать какой-либо запрос.
Первый - не использовать пустые идентификаторы в параметрах запроса.Вместо этого создайте большое случайное число и сделайте из этого ссылку.Вам нужно будет сохранить таблицу в вашей базе данных, сопоставляя ваши случайные числа с фактическими идентификаторами, которые они представляют, и вам придется в конечном итоге очистить таблицу.Это довольно просто реализовать, но требует некоторого пространства для хранения, а иногда и некоторого управления хранимыми данными.
Второй способ - подписать данные при создании ссылки.Добавляя криптографическую подпись к данным и проверяя подпись при выполнении запроса, вы гарантируете, что только ваша веб-служба могла создать ссылку.Даже если сам запрос «подделан» - возможно, добавлен в закладки, записан, скопирован и вставлен в другой браузер - вы знаете, что ваш сайт уже разрешил этот URL.
Для этого вам нужносоздать код аутентификации сообщений (MAC) с данными, которые вы подписываете (скажем, просто значением 'id', или, возможно, идентификатором и временем, когда вы подписали данные) и с секретным ключом, который вы храните только на своемserver.
Затем, по вашему мнению, вы берете значение id (или id и метку времени, если это то, что вы используете), и вы снова создаете MAC, и смотрите, совпадают ли они.Если есть какая-либо разница, вы отклоняете запрос как подделанный.
Посмотрите документы на python для модуля hmac , а также модуль hashlib длявсе детали.
Вы можете создать ссылку на Python, как это:
settings.py:
hmac_secret_key = '12345'
views.py:
import time, hmac, hashlib
from django.conf import settings
def some_view(request):
...
id = 5
time = int(time.time())
mac = hmac.new(
settings.hmac_secret_key,
'%d/%d' % (id, time),
hashlib.sha1)
url = 'http://www.example.com/posts/id=%d&ts=%d&mac=%s' % (
id, time, mac.hexdigest())
# Now return a template with that url in it somewhere
Чтобы проверить это в другом представлении, вы должны использовать код, подобный следующему: (предупреждение, предупреждение, не надежный, много проверки ошибок еще предстоит сделать)
def posts_view(request):
id = int(request.GET['id'])
ts = int(request.GET['ts'])
mac_from_url = request.GET['mac']
computed_mac = hmac.new(
settings.hmac_secret_key,
'%d/%d' % (id, time),
hashlib.sha1)
if mac_from_url <> computed_mac:
raise SomeSecurityException()
# Now you know that the request is legit.
# You can check the timestamp here, too, if you like.