3 горизонтальные линии, бургер
3 горизонтальные линии, бургер
3 горизонтальные линии, бургер
3 горизонтальные линии, бургер

3 горизонтальные линии, бургер
Удалить все
ЗАГРУЗКА ...

Содержание



    Сделать систему авторизации и регистрации пользователей на Django

    Часы
    16.10.2023
    /
    Часы
    11.03.2026
    /
    Часы
    6 минут
    Глазик
    906
    Сердечки
    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 %} <div class="form"> <form enctype="multipart/form-data" class="form_form" id="toSignup" action="send_new_user" method="get"> <div> <input class="form_el" placeholder="имя" type="text" name="username" id="username"> <div class="hint-container"> <p id="username-error" class="hint-required">обязательно</p> <p class="hint-error">от 3 до 25 букв</p> </div> </div> <div> <input class="form_el" placeholder="почта" type="email" name="email" id="email"> <div class="hint-container"> <p id="email-error" class="hint-required">обязательно</p> <p class="hint-error">корректный адрес почты</p> </div> </div> <div> <input class="form_el" placeholder="пароль" type="password" name="password" id="password"> <div class="hint-container"> <p id="password-error" class="hint-required">обязательно</p> <p class="hint-error">от 6 букв</p> </div> </div> <div> <input class="form_el" placeholder="повтори пароль" type="password" name="repeated_password" id="repeated_password"> <div class="hint-container"> <p id="repassword-error" class="hint-required">обязательно</p> <p class="hint-error">должен совпадать с паролем</p> </div> </div> <textarea class="form_el__about" placeholder="Раскажи немного о себе" name="about" rows=4 id="about"></textarea> </form> </div> <div class="sel_file"> <label for="texta">Выбери себе аватар.</label> <input class="form_el__file" placeholder="выбрать файл" type="file" name="file" id="file"> </div> <div class="buttons"> <div id="signup" class="button button-middle"> <a>Регистрация</a> </div> </div>
    А в самом низу перед тегом body вставить написаный заранее скрипт
    <!-- Загрузка jQuery --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> {% csrf_token %} <!-- Нужно сохранить csrf токен в JS переменную чтобы потом использовать в написанном ранее скрипте --> <script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; </script> <!-- Загрузка ранее написанного скрипта запроса регистрации --> <script src="{% static 'User/js/signup.js' %}"></script>

    Донастраиваем 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")

    Пишем шаблон аутентификации на сайт

    Ну и конечно мой шаблон для входа на сайт
    <div id="common-error" class="hint-container hint-required hint-common_error"></div> {% csrf_token %} <div class="form"> <form class="form_form form_login" id="toLogin" action="send_new_user" method="get"> <div> <input class="form_el" placeholder="имя" type="text" name="username" autocomplete="off" id="username"><br><br> <div class="hint-container"> <p id="username-error" class="hint-required">обязательно</p> </div> </div> <div> <input class="form_el" placeholder="пароль" type="password" name="password" autocomplete="off" id="password"><br><br> <div class="hint-container"> <p id="password-error" class="hint-required">обязательно</p> </div> </div> </form> </div> <div class="buttons"> <div id="login" class="button button-middle"> <a>Вход</a> </div> <div class="button button-middle"> <a href="{% url 'signup' %}"> Регистрация </a> </div> </div>
    И конечно же незабываем вставить скрипт в шаблон. Написаный нами login.js и jQuery библиотеку
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> {% csrf_token %} <script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; </script> <script src="{% static 'User/js/login.js' %}"></script>

    Вывод

    В данном кейсе я продемонстрировал две основные формы для системы аутентификации пользователей. Форму регистрации и форму входа. Не самое сложное дело, особенно если знаешь что делаешь.
    Сразу хочу оговориться, я не добавлял сюда капчу или проверку почты по одной простой причине. Это аутентификация на моём сайте и мне этого не требовалось. В моей деятельности важно не количество пользователей, а их качество. То есть, если человек захочет связаться со мной он свяжется, если нет ну это его дело.

    Дополнительные материалы

    Github репозиторий

    Репозиторий, который я использую чтобы разрабатывать данный сайт
    Конкретно в данном кейсе вас будут интересовать следующие файлы:

    Материалы которыми пользовался


    Не забудь поделиться, лайкнуть и оставить комментарий)

    Комментарии

    (0)

    captcha
    Отправить
    ЗАГРУЗКА ...
    Сейчас тут пусто. Буть первым (o゚v゚)ノ

    Другое

    Похожие статьи


    Как реализовать регистрацию и логирование пользователей

    Часы
    30.10.2023
    /
    Часы
    11.03.2026
    Глазик
    1049
    Сердечки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Соединённые точки
    0
    Сразу оговорюсь, что система аутентификации, которую мы с тобой будем писать не основана на встроеном приложении django, django.contrib.auth . Это будет отдельное приложение с отдельной моделью к ней.

    Как построить API для сайта используя Django REST API

    Часы
    24.02.2025
    /
    Часы
    11.03.2026
    Глазик
    4449
    Сердечки
    0
    Соединённые точки
    1
    Соединённые точки
    6
    Соединённые точки
    0
    Здесь ты узнаешь как написать свой API используя Django REST API. Добавляется он для того, чтобы построить API для доступа со стороны клиента (фронтенда). Так же демонстрирую как данный API …

    Использованные термины


    Релевантные вопросы