"get()" Запись из БД Django SQLite3 ПОСЛЕ шифрования с помощью django_cryptography
Я создал Django-приложение, в котором прошу посетителя сайта ввести свое имя в форму. После отправки POST-файла, он сохраняет его имя и IP-адрес, с которого он зашел на сайт, в базе данных SQLite3. Для тренировки я шифрую IP-адрес перед сохранением в базе данных.
Если пользователь "возвращается" на сайт, мой код настроен на поиск записи для этого пользователя в базе данных сначала на основе его IP-адреса. Если в базе данных уже есть запись с таким IP, то выводится сообщение "Добро пожаловать обратно".
Если я не шифрую IP, мое приложение работает нормально, но когда я пытаюсь использовать django_cryptography
, я застреваю.
Что у меня есть на данный момент:
models.py
from django.db import models
from django import forms
from django_cryptography.fields import encrypt
INT_MAX_NAME_STRING_LENGTH = 100
# Previous visitors object
class Previous_Visitor_Model(models.Model):
visitor_name = models.CharField(max_length=INT_MAX_NAME_STRING_LENGTH)
visitor_ip = encrypt(models.CharField(max_length=16)) # IP_Address_Field()
# The name form on the initial page
class NameForm(forms.Form):
visitor_name = forms.CharField(label='Your (company) name', max_length=INT_MAX_NAME_STRING_LENGTH)
Поэтому я шифрую их IP-адрес в модели. Когда посетитель вводит свое имя в форму и отправляет ее, в базе данных создается новая запись с его именем и BLOB
в качестве зашифрованного значения IP-адреса. Если я не использую здесь шифрование, то вместо этого сохраняется что-то вроде 127.0.0.1
, что и должно быть.
Теперь, как вы увидите в views.py
ниже, я пытаюсь get()
получить запись из базы данных по current_visitors_ip
. Опять же, без шифрования это работает нормально, но поскольку я зашифровал IP, он не находит записи. Мое предположение заключается в том, что я пытаюсь сравнить строковое значение 127.0.0.1
в качестве переменной current_visitors_ip
со значениями BLOB
, которые он получает из базы данных, поэтому я также попробовал бросить encrypt()
вокруг переменной current_visitors_ip
, думая, что эти два значения ДОЛЖНЫ быть одинаковыми, но это все еще не работает.
Вот отличная статья здесь о том, как разрешить шифрование/дешифрование значений при запросе к базе данных, но это предполагает использование отдельных функций шифрования/дешифрования, что не конец света, но мне нравится идея использовать для этого криптографическую библиотеку django. Идеально, если бы он мог ДЕКРИПТИРОВАТЬ значения, которые он get()
берет из базы данных, это было бы идеально, но я не думаю, что у них есть такая функция.
Я знаю, что это медленный способ, я просто хочу попрактиковаться. Вот логика views.py.
views.py
from django.shortcuts import render
from .models import Previous_Visitor_Model, NameForm
from django.http import HttpResponseRedirect
from django_cryptography.fields import encrypt
# Helper Function to get the current visitor's IP address
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
ip = str(ip)
return ip
# Create your views here.
# Initial visit logic
def initial_visit_view(request):
# Get the current visitor's IP Address
current_visitors_ip = get_client_ip(request)
# If the current visitor has never been here before, based on their ip ...
try:
existing_user = Previous_Visitor_Model.objects.get(visitor_ip=current_visitors_ip)
except:
existing_user = None
# Create a new record in the db for this user's name and IP
if existing_user == None:
if request.method == 'POST':
# Create a form instance and populate it with data from the request:
form = NameForm(request.POST)
if form.is_valid():
# Save the user's data (upon POST of name)
Previous_Visitor_Model(visitor_name=form.cleaned_data['visitor_name'], visitor_ip=current_visitors_ip).save()
# redirect to a new URL:
return HttpResponseRedirect('/projects/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
context = {'form': form}
return render(request, 'first_visit.html', context)
# Else if they're a repeat visitor
elif existing_user != None:
context = {
'current_visitor': existing_user
}
return render(request, 'repeat_visit.html', context)
UPDATE
Полагаю, что лучшим способом было бы просто хэшировать IP-адреса перед сохранением их в базе данных, и просто сравнивать хэши, как описано здесь, но просто интересно, есть ли ответ на мой вопрос. Спасибо!