Куки и сессии Django
Cookie — это текстовый файл, хранящийся на компьютере клиента и содержащий различную информацию для отслеживания.
Идентификация возвращающихся пользователей включает три шага:
- Серверный скрипт отправляет браузеру набор cookie. Например: имя, возраст или идентификационный номер и т. д.
- Браузер сохраняет эту информацию на локальном компьютере для будущего использования.
- В следующий раз, когда браузер отправляет любой запрос веб-серверу, браузер отправляет эту информацию cookie на сервер, и сервер использует эту информацию для идентификации пользователя.
HTTP — это протокол «без сохранения состояния», что означает, что каждый раз, когда клиент получает веб-страницу, клиент открывает отдельное соединение с веб-сервером, и сервер автоматически не сохраняет никаких записей о предыдущих запросах клиента.
Однако по-прежнему существуют следующие три способа поддержания сессии между веб-клиентом и веб-сервером:
Cookies
Веб-сервер может назначить уникальный идентификатор сессии в виде cookie каждому веб-клиенту, и для последующих запросов клиента полученный cookie может использоваться для его идентификации.
В веб-разработке сессия используется для отслеживания сессии, и в основе сессии лежит технология cookie.

Синтаксис cookie в Django
Установить cookie:
rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密盐',...)
Получить cookie:
request.COOKIES.get(key)
Удаление cookie:
rep =HttpResponse || render || redirect rep.delete_cookie(key)


Создание приложений и моделей
models.py
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)

urls.py
from django.urls import path
from cookie import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('index/', views.index),
path('logout/', views.logout),
path('order/', views.order)

views.py
if request.method == "GET":
return render(request, "login.html")
username = request.POST.get("username")
password = request.POST.get("pwd")
user_obj = models.UserInfo.objects.filter(username=username, password=password).first()
print(user_obj.username)
if not user_obj:
return redirect("/login/")
else:
rep = redirect("/index/")
rep.set_cookie("is_login", True)
return rep
def index(request):
print(request.COOKIES.get('is_login'))
status = request.COOKIES.get('is_login') # Когда браузер отправляет очередной запрос, определите, является ли cookie, которую он несёт, cookie, установленной в ответе при успешном входе.
if not status:
return redirect('/login/')
return render(request, "index.html")
def logout(request):
rep = redirect('/login/')
rep.delete_cookie("is_login")
return rep # Выполнить после нажатия кнопки выхода из системы, удалить cookie, больше не сохранять состояние пользователя и перенаправить на страницу входа
def order(request):
print(request.COOKIES.get('is_login'))
status = request.COOKIES.get('is_login')
if not status:
return redirect('/login/')
return render(request, "order.html")
Далее создаются три файла шаблонов: login.html, index.html, order.html.
login.html
index.html
order.html
Результат выполнения показан на рисунке ниже:

Сессия (пары ключ-значение, хранящиеся на стороне сервера)
Когда сервер работает, он может создавать выделенный объект сессии для каждого браузера пользователя. Поскольку сессия принадлежит исключительно браузеру пользователя, когда пользователи обращаются к веб-ресурсам сервера, они могут сохранять свои данные в своих собственных сессиях. Когда пользователи впоследствии обращаются к другим веб-ресурсам на сервере, эти другие веб-ресурсы извлекают данные из соответствующих сессий пользователей, чтобы обслуживать пользователей.

Как это работает
-
a. Сначала браузер запрашивает страницу входа.
-
b. Когда браузер вводит аккаунт и пароль для второго запроса, если ввод правильный, сервер отвечает браузеру главной страницей и cookie, ключ которого — sessionid, а значение — случайная строка, т. е. set_cookie("sessionid", random_string).
-
c. Внутри сервер сохраняет запись в таблице django.session.
В таблице django.session есть три поля.
- session_key: хранит случайную строку, т. е. значение, соответствующее ключу sessionid в cookie, отправленном браузеру.
- session_data: хранит информацию пользователя, т. е. несколько записей вида request.session["key"]=value, и это шифротекст.
- expire_date: хранит время истечения срока действия этой записи (по умолчанию 14 дней).
d. Когда браузер в третий раз запрашивает другие ресурсы, он передаёт cookie: {sessionid: random_string}. Сервер извлекает данные пользователя из таблицы django.session на основе случайной строки, чтобы пользователь мог их использовать (т. е. сохранение состояния).
Примечание:Таблица django.session хранит информацию о браузере, а не информацию о каждом пользователе. Поэтому запросы от нескольких пользователей, использующих один и тот же браузер, сохраняют только одну запись (последняя перезаписывает предыдущую), и только запросы из нескольких браузеров сохраняют несколько записей.
Куки компенсируют отсутствие состояния в HTTP, позволяя серверу узнать, «кто» этот человек. Однако куки хранятся в браузере в виде текста, что менее безопасно, а максимальный поддерживаемый размер составляет всего 4096 байт. Поэтому используйте куки только для идентификации разных пользователей, а приватную информацию и текст, превышающий 4096 байт, храните в соответствующей сессии.
настройки сессии:
request.session["key"] = value
Шаги выполнения:
- a. Сгенерировать случайную строку
- b. Сохранить случайную строку и заданные пары ключ-значение в session_key и session_data таблицы django_session.
- c. Настройкиcookie: set_cookie("sessionid", случайная строка)Ответить браузеру
получение сессии:
request.session.get('key')
Шаги выполнения:
- a. Получить значение ключа sessionid из куки, то есть случайную строку.
- b. Отфильтровать запись из таблицы django_session по случайной строке.
- c. Получить данные из поля session_data.
Удаление сессии: удалить всю запись (включая три поля session_key, session_data, expire_date):
request.session.flush()
Удалить одну из пар ключ-значение в session_data:
del request.session["key"]
Шаги выполнения:
- a. Получить значение ключа sessionid из куки, то есть случайную строку.
- b. Отфильтровать запись из таблицы django_session по случайной строке.
- c. Удалить отфильтрованные записи
Пример
Создать маршрут:
urls.py
urlpatterns = [
path('session_login/', session_views.login),
path('s_index/', session_views.s_index),
path('s_logout/', session_views.s_logout),
]
Создать функцию представления:
views.py
if request.method == "GET":
return render(request, "login.html")
username = request.POST.get("username")
password = request.POST.get("pwd")
user_obj = models.UserInfo.objects.filter(username=username, password=password).first()
print(user_obj.username)
if not user_obj:
return redirect("/session_login/")
else:
request.session['is_login'] = True
request.session['user1'] = username
return redirect("/s_index/")
def s_index(request):
status = request.session.get('is_login')
if not status:
return redirect('/session_login/')
return render(request, "s_index.html")
def s_logout(request):
# del request.session["is_login"] # Удалить набор пар ключ-значение в session_data
request.session.flush() # Удалить одну запись, включая (session_key session_data expire_date), три поля
return redirect('/session_login/')
Файл шаблона:
s_index.html
Результат выполнения показан на рисунке ниже:
