Сделать систему авторизации и регистрации пользователей на Django
16.10.2023
18.12.2024
6 минут
233
0
0
0
0
Задача
Реализовать систему аутентификации пользователей. Для этого создаётся форма регистрации и форма для входа и выхода на сайте timthewebmaster.com.
Форма регистрации должна содержать следующие элементы:
- имя пользователя ( требовать обязательно )
- почту пользователя ( требовать обязательно )
- пароль пользователя ( требовать обязательно )
- повтор пароля пользователя ( требовать обязательно )
- поле об самом пользователе
- запрос аватарки пользователя
- кнопки регистрации соответственно
Форма входа должна состоять только из двух полей:
- имя пользователя
- пароля пользователя
Ещё должна быть кнопка, которая бы позволяла выйти из режима аутентифицированного пользователя.
Решение
Подключение jQuery
Для решения данного кейса мне потребуется подключить одну библиотеку JS, jQuery. Это популярная , простая библиотека. И изменить настройки безопасности сайта написаного на django. То есть подправить файл settings.py
Предварительная настройка django для регистрации пользователей
На самом деле это необязательный шаг, ибо это не помешает общению сервера с клиентом. Но ради безопасности и уверенности, что никакие хакеры не взломают базу данных сервера и не получат конфиденциальные данные пользователей мы это настроим.
В файле settings.py добавь
CSRF_USE_SESSIONS = True
В приложении которое выполняет регистрацию открой urls.py и добавь 2 путя
from django.urls import path
from .views import signup, signup_verify
urlpatterns = [
…
# Это путь на страницу которая будет видна пользователю
path('signup/', signup, name='signup'),
# Это путь/адрес который мы будем использовать чтобы общаться с сервером
path('signup/verify-signup/', signup_verify, name='signup_verify'),
]
Пишем ajax запрос для формы регистрации
Теперь пишется JS-скрипт с запросом.
function OnSignup(){
// Данные которые мы запросили у пользователя и которые мы отправим на сервер
var form_data = new FormData();
// Токен защиты ( про который говорилось выше)
form_data.append("csrfmiddlewaretoken", csrftoken);
// Имя пользователя
form_data.append("username", $("#username").val())
// Почта пользователя
form_data.append("email", $("#email").val())
// Пароль пользователя
form_data.append("password", $("#password").val())
// Повтор пароля пользователя ( нужно будет сопоставить с первым)
form_data.append("repeated_password", $("#repeated_password").val())
// О пользователе
form_data.append("about", $("#about").val())
// Аватарка пользователя
form_data.append("file", document.getElementById('file').files[0]);
$.ajax({
// Тип запроса. POST потому что мы не хотим чтобы данные были видны
type: "POST",
// Путь который мы задали для общения с сервером
url: "verify-signup/",
// Отправляемые данные
data: form_data,
processData: false,
contentType: false,
// Отправляем токен защиты
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
// Функция которая будет выполнена при успехе, код 200
success: function(result) {
$(".hint-required").css("color","green")
$("#common-error").text(result.common)
$("#username-error").text(result.username)
$("#email-error").text(result.email)
$("#password-error").text(result.password)
$("#repassword-error").text(result.password)
// Redirect to login page
setTimeout(function(){
window.location.href = '/login/'
},3000)
},
// Функция которая будет выполнена при неудаче
error: function(jqXHR, textStatus, errorThrown){
$(".hint-required").css("color","red")
$("#common-error").text(jqXHR.responseJSON.common)
$("#username-error").text(jqXHR.responseJSON.username)
$("#email-error").text(jqXHR.responseJSON.email)
$("#password-error").text(jqXHR.responseJSON.password)
$("#repassword-error").text(jqXHR.responseJSON.password)
}
});
}
// Документ готов и загружен
$(document).ready( function(){
// Пользователь нажал на кнопку регистрации
$("#signup").on('click',OnSignup)
})
При успехе, то есть если все проверки пройдены, по типу длины пароля или существующей почты, мы вставим текст для обратной связи с пользователем и перенаправим на страницу входа.
При неудаче, мы сообщим об этом пользователю тоже.
Пишем функцию обработки ajax формы регистрации
В главе предварительной настройки мы импортировали в utls.py функцию signup_verify давай определим её
from django.shortcuts import render
from django.http import JsonResponse, HttpResponseRedirect
from django.template.defaultfilters import slugify
import re
from MyBlog import settings
from .models import User
...
def signup_verify(request):
message = {
'common': '',
'username': 'обязательно',
'email': 'обязательно',
'password': 'обязательно',
'repassword': 'обязательно',
}
status = 200
# Будем обрабатывать только POST запросы
if request.method == 'POST':
# Общий паттерн почты для сравнения
regex = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b'
# Собираем данные которые отправили
username = request.POST['username']
email = request.POST['email']
password = request.POST['password']
repeated_password = request.POST['repeated_password']
about = request.POST['about']
avatar = None
try:
avatar = request.FILES['file']
except:
avatar = None
message['common']='✖ не могу зарегестрировать нового пользователя'
# Имя, почта, пароль пусты
if len(username) == 0:
message['username']='⚠ поле пользователя не заполнено'
status = 406
if len(email) == 0:
message['email']='⚠ поле почты не заполнено'
status = 406
if len(password) == 0:
message['password']='⚠ поле пароля не заполнено’
status = 406
# Проверка если пользователь уже существует
if User.objects.filter(name=username).exists() or User.objects.filter(slug=slugify(username)).exists():
message['username']='⚠ пользователь с таким именем уже существует'
status = 406
# Проверка если пользователь уже существует
if User.objects.filter(email=email).exists():
message['email']='⚠ такая почта уже используется'
status = 406
# Проверка если имя достаточно длинное
if len(username) < 3:
message['username']='⚠ введённое имя слишком короткое'
status = 406
# Проверка если имя слишком длинное
if len(username) > 25:
message['username']='⚠ введённое имя слишком длинное'
status = 406
# Проверка если пароль достаточно длинный
if len(password) < 6:
message['password']='⚠ введённый пароль слишком короткий'
status = 406
# Совпадают ли пароли
if password != repeated_password:
message['password']='⚠ пароль не совпадает'
message['repassword']='⚠ пароль не совпадает'
status = 406
# Правильный ли формат у почты
if not re.fullmatch(regex, email):
message['email']='⚠ неправильный формат адреса почты'
status = 406
if status == 200:
message['common'] = '✔ вы успешно зарегестрировались, перенаправление'
message['username'] = '✔ Хорошо'
message['email'] = '✔ Хорошо'
message['password'] = '✔ Хорошо'
message['repassword'] = '✔ Хорошо'
# Сохраняем данные из отправленной формы
user = User(name=username, about=about, avatar=avatar, email=email, password=password)
user.save()
return JsonResponse(message, status=status)
else:
status = 403
return JsonResponse(message, status=status)
Вот таким образом я выявляю “ошибки” форм в django.
Собираем всё вместе в html шаблоне. Страница регистрации
Теперь, чтобы всё заработало, мне нужно создать шаблон, который бы загрузил соответствующий скрипт и стили, использовал токен.
Вот код формы
{% csrf_token %}
А в самом низу перед тегом body вставить написаный заранее скрипт
{% csrf_token %}
Донастраиваем URLs для формы аутентификации пользователей
Нужно добавить 2 дополнительных путя и импортировать соответствующие функции
...
from .views import login, login_verify, logout
urlpatterns = [
…
# Эта функция очистит сессию от созданных ранее переменных
path('logout/', logout, name='logout'),
# Эта функция отобразит форму входа для пользователя
path('login/', login, name='login'),
# Эта функция задаст соответствующие переменные сессии для соответствующего пользователя и решит можен ли он войти или нет
path('login/verify-login/', login_verify, name='login_verify'),
]
Пишем ajax запрос для формы аутентификации пользователя
Принцип тот же что и при регистрации. Указываем тип запроса, url-запроса и данные которые хотим передать. Ну и дополнительно, конечно, обратная связь для пользователя. Чтобы он знал об ошибках которые он допустил при заполнении формы. Всё это в отдельном файле login.js
function OnLogin(){
var username = $("#username").val()
var password = $("#password").val()
$.ajax({
type: "POST",
url: 'verify-login/',
data: {
'username': username,
'password': password,
},
headers: {'X-CSRFToken': csrftoken},
mode: 'same-origin',
success: function(result){
$(".hint-required").css("color","green")
$("#common-error").text(result.common)
$("#username-error").text(result.username)
$("#password-error").text(result.password)
setTimeout(function(){
window.location.href = '/' + language_code + '/'
},1000)
},
error: function(jqXHR, textStatus, errorThrown){
$(".hint-required").css("color","red")
$("#common-error").text(jqXHR.responseJSON.common)
$("#username-error").text(jqXHR.responseJSON.username)
$("#password-error").text(jqXHR.responseJSON.password)
}
})
}
// Документ готов и загружен
$(document).ready( function(){
// Пользователь нажал на кнопку входа
$("#login").on('click',OnLogin)
})
Пишем функцию/форму обработки ajax запроса аутентификации пользователя
Вот готовые функции для обработки и проверки данных введённых пользователем
def login_verify(request):
message = {
'common': '',
'username': 'обязательно',
'password': 'обязательно',
}
status = 200
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
message['common']='✖ не могу войти'
if len(username) == 0:
message['username']='⚠ пользователь пуст'
status = 406
if len(password) == 0:
message['password']='⚠ пароль пуст'
status = 406
required_user = User.objects.filter(name=username)
# Пользователь существует
if required_user.exists():
Введённый пароль совпадает с сохранённым
if required_user.first().password == password:
status = 200
# Задаём статус текущей сессии как зарегестрированной
request.session["is_auth"] = True
# Сохраняем имя пользователя в переменной текущей сессии
# Это может пригодиться для отображения информации предназначеной
# Только пользователю
request.session["username"] = username
message['common'] = '✔ Вы успешно вошли, перенаправление ... '
message['username'] = '✔ Хорошо'
message['password'] = '✔ Хорошо'
else:
message['password'] = '⚠ Неправильный пароль'
status = 406
else:
message['username'] = '⚠ Такого пользователя не существует'
status = 406
return JsonResponse(message, status=status)
Функция выхода пользователя. Я просто очищаю текущую сессию пользователя на моём сайте. И перенаправляю на страницу входа на сайт.
def logout(request):
request.session.flush()
return HttpResponseRedirect("/login")
Пишем шаблон аутентификации на сайт
Ну и конечно мой шаблон для входа на сайт
{% csrf_token %}
И конечно же незабываем вставить скрипт в шаблон. Написаный нами login.js и jQuery библиотеку
{% csrf_token %}
Вывод
В данном кейсе я продемонстрировал две основные формы для системы аутентификации пользователей. Форму регистрации и форму входа. Не самое сложное дело, особенно если знаешь что делаешь.
Сразу хочу оговориться, я не добавлял сюда капчу или проверку почты по одной простой причине. Это аутентификация на моём сайте и мне этого не требовалось. В моей деятельности важно не количество пользователей, а их качество. То есть, если человек захочет связаться со мной он свяжется, если нет ну это его дело.
Дополнительные материалы
Github репозиторий
Репозиторий, который я использую чтобы разрабатывать данный сайт
Конкретно в данном кейсе вас будут интересовать следующие файлы:
- Скрипт написаный на jQuery для регистрации
- Скрипт написаный на jQuery для входа
- Настройка ulrs
- Непосредственно функция рендеринга страницы, signup login logout
- И конечно шаблон который django использует для отрисовки формы регисрации
- И конечно шаблон который django использует для отрисовки формы входа
Материалы которыми пользовался
Комментарии
(0)
Отправить
Сейчас тут пусто. Буть первым (o゚v゚)ノ
Другое
Использованные термины
- Django шаблон ⟶ Это текстовый документ, который размечен специальным ситнаксисом для вставки кода в него.
- Джанго представления ⟶ Это функции или классы, которые обрабатывают HTTP-запросы и возвращают HTTP-ответы. Они отвечают за бизнес-логику вашего приложения и связаны с моделями данных, чтобы взять информацию из базы данных и отобразить её пользователю.
- Джанго фреймворк ⟶ Это высокоуровневый веб-фреймворк на языке программирования Python, который позволяет разработчикам создавать веб-приложения быстрее и с меньшими затратами на время благодаря своим мощным инструментам и встроенным функциям. Он был разработан для упрощения разработки сложных веб-сайтов и предоставляет множество «из коробки» функций
- Вебсайт ⟶ Это совокупность связанных между собой веб-страниц, доступных через интернет и имеющих одно общее доменное имя. Каждый веб-сайт может содержать текстовую информацию, изображения, видео и другие мультимедийные элементы. Веб-сайты могут выполнять различные функции, включая предоставление информации, общение, онлайн-торговлю и множество других взаимодействий.
Релевантные вопросы
- Ты предлагаешь SEO услуги ? Нет. Пока нет. Понимаете ли, продвижение сайтов это долгий процесс да и опыта у меня не столь много в продвижении. 2 сайта всего. Да даже если бы и опыт был более значительным, не думаю что я стану предлагать комплексные услуги по продвижению сайтов. Возможно какие-нибуль измеримые работы и услуги. По типу гостевого постинга или заработок ссылок.
- Почему, создавая сайт ты предпочёл django, а не конструкторы сайтов ? Довольно сложный вопрос. Наверное я люблю разбираться и копаться в сложных вещах, хотя вроде бы и не стоило. Тут похожая история с играми. Вместо того, чтобы делать игры на игровых движках, я делал свой собственный, **DI**. Ну, я просто не ищу простых путей ;)
- Мое приложение некорректно отображается на сервере? Если это не работает, в 99% случаев это проблема конфигурации. Отсутствующее свойство, неправильный порядок вызовов или отсутствующий компонент — серверный рендеринг строго относится к конфигурации. Лучший способ выяснить, что не так, — сравнить свой проект с уже работающей настройкой. Ознакомьтесь с эталонными реализациями по частям.