Django 및 Ajax: 웹 애플리케이션에 대한 실시간 양식 유효성 검사가 포함된 강력한 인증 및 권한 부여 시스템 - 3

이전 부분에서는 사용자 지정 인증 백엔드로 사용자 지정 로그인 흐름을 설정하여 사양의 이 부분을 충족했습니다.

..Users can either login with any of Email/Password or Username/Password combination...



이 부분의 사양에서 요구하는 기능을 계속 구현할 것입니다. 특히 students registration 흐름을 처리합니다.

이 프로젝트의 경우(사양을 준수하기 위해) 다음 단계에 따라 등록됩니다.
  • 사용자는 등록 양식에 세부 정보를 입력합니다.
  • 유효한 경우 등록 시 제공된 이메일 주소로 메일이 전송됩니다. 그럼
  • 확인 시 한 거래에만 유효한 제공된 링크를 클릭하면 사용자가 로그인할 수 있습니다.

  • 소스 코드



    이 시점까지의 소스 코드는 github에서 호스팅되며 전체 애플리케이션의 소스 코드는 다음과 같습니다.


    시르네이 / django_real_time_validation


    Django 및 Ajax: 웹 애플리케이션에 대한 실시간 양식 유효성 검사가 포함된 강력한 인증 및 권한 부여 시스템





    django_real_time_validation


    Django 및 Ajax: 웹 애플리케이션에 대한 실시간 양식 유효성 검사가 포함된 강력한 인증 및 권한 부여 시스템



    View on GitHub



    5단계: 학생 등록 ​​양식



    텍스트 편집기에서 aacounts/forms.py를 열고 다음을 추가해 보겠습니다.

    # accounts > forms.py
    ...
    from django.contrib.auth import get_user_model
    from django.contrib.auth.forms import UserCreationForm
    
    ...
    
    class StudentRegistrationForm(UserCreationForm):
        username = forms.CharField(
            widget=forms.TextInput(attrs={"placeholder": "Student number e.g. CPE/34/2367"})
        )
    
        def __init__(self, *args, **kwargs):
            super(StudentRegistrationForm, self).__init__(*args, **kwargs)
            for visible in self.visible_fields():
                visible.field.widget.attrs["class"] = "validate"
    
        class Meta:
            model = get_user_model()
            fields = (
                "first_name",
                "last_name",
                "username",
                "email",
                "level",
                "gender",
                "password1",
                "password2",
            )
    
    


    Django의 UserCreationForm 에서 상속받은 단순한 형태입니다. 이것은 one of the built-in forms in the framework 입니다. UserCreationForm는 사용자를 생성하기 위해 사용자 모델(username, password1 및 password2)에서 상속된 세 개의 필드가 있는 단순한 ModelForm입니다. 양식이 AJAX를 사용하여 처리되기 때문에 이것은 필요하지 않을 수 있습니다. 여전히 그것을 사용하는 것을 선호합니다.

    6단계: 학생 등록을 위해 utils.py 작성



    사양에서 학생 등록에 대한 모든 문제를 해결하려면 다음을 수행하십시오.

    ...For students, their usernames must start with CPE and must be at least 9 characters long not counting any forward slash that it contains...



    충족되는지 확인하기 위해 몇 가지 도우미 함수를 작성하기 시작할 것입니다.
    accounts/utils.py로 이동하여 다음으로 채웁니다.

    # accounts > utils.py
    
    import re
    
    from django.contrib.auth import get_user_model
    from django.contrib.auth.password_validation import validate_password
    from django.core import exceptions
    
    USERNAME_MIN_LENGTH = 9
    
    
    def is_valid_username(username):
        if get_user_model().objects.filter(username=username).exists():
            return False
        if not username.lower().startswith("cpe"):
            return False
        if len(username.replace("/", "")) < USERNAME_MIN_LENGTH:
            return False
        if not username.isalnum():
            return False
        return True
    
    
    def is_valid_password(password, user):
        try:
            validate_password(password, user=user)
        except exceptions.ValidationError:
            return False
        return True
    
    
    def is_valid_email(email):
        if get_user_model().objects.filter(email=email).exists():
            return False
        if not re.match(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", email):
            return False
        if email is None:
            return False
        return True
    
    
    def validate_username(username):
        if get_user_model().objects.filter(username=username).exists():
            return {
                "success": False,
                "reason": "User with that matriculation number already exists",
            }
        if not isinstance(username, six.string_types):
    
            return {
                "success": False,
                "reason": "Matriculation number should be alphanumeric",
            }
    
        if len(username.replace("/", "")) < USERNAME_MIN_LENGTH:
            return {
                "success": False,
                "reason": "Matriculation number too long",
            }
    
        if not username.isalnum():
    
            return {
                "success": False,
                "reason": "Matriculation number should be alphanumeric",
            }
    
        if not username.lower().startswith("cpe"):
            return {
                "success": False,
                "reason": "Matriculation number is not valid",
            }
    
        return {
            "success": True,
        }
    
    
    def validate_email(email):
        if get_user_model().objects.filter(email=email).exists():
            return {"success": False, "reason": "Email Address already exists"}
        if not re.match(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b", email):
            return {"success": False, "reason": "Invalid Email Address"}
        if email is None:
            return {"success": False, "reason": "Email is required."}
        return {"success": True}
    
    


    와 💔!!! 그것은 해독하기에는 너무 많은 것입니다. 친구야 미안해, 한번 해보자. is_valid_username 함수에서는 사용자가 모든 테스트를 통과했는지만 확인합니다.
  • 중복된 사용자 이름 없음:

  •   ...
      if get_user_model().objects.filter(username=username).exists():
            return False
    


  • 학생의 사용자 이름은 CPE로 시작해야 합니다.

  •   if not username.lower().startswith("cpe"):
            return False
    


  • 사용자의 사용자 이름은 슬래시 없이 9자 이상이어야 합니다.

  •   if len(username.replace("/", "")) < USERNAME_MIN_LENGTH:
            return False
    


    마지막은 사용자 이름이 영숫자( isalnum() )인지 확인하는 것입니다.

    마찬가지로 is_valid_password()는 django의 validate_password 을 사용하여 사용자 암호가 django의 암호 유효성 검사를 통과하도록 합니다.
    is_valid_email() 제공된 이메일 주소가 None이 아니고 고유하며 일반 이메일 패턴(예: person@domain)을 따르도록 합니다.

    모든 validate_*()는 실시간 유효성 검사를 위한 도우미 함수입니다.
    views.py 파일에서 사용하겠습니다.

    # accounts > views.py
    ...
    from django.http import JsonResponse
    ...
    from . import utils
    ...
    
    def validate_email(request):
        email = request.POST.get("email", None)
        validated_email = utils.validate_email(email)
        res = JsonResponse({"success": True, "msg": "Valid e-mail address"})
        if not validated_email["success"]:
            res = JsonResponse({"success": False, "msg": validated_email["reason"]})
        return res
    
    def validate_username(request):
        username = request.POST.get("username", None).replace("/", "")
        validated_username = utils.validate_username(username)
        res = JsonResponse({"success": True, "msg": "Valid student number."})
        if not validated_username["success"]:
            res = JsonResponse({"success": False, "msg": validated_username["reason"]})
        return res
    
    


    우리는 단지 유틸리티를 활용하고 있는 것입니다, 그렇죠? POST 요청에서 값을 가져온 후 일부 json 데이터를 반환하도록 미리 준비한 함수에 전달됩니다.

    다음을 urls.py 파일에 추가하십시오.

    urlpatterns = [
    ...
    path("validate-username/", views.validate_username, name="validate_username"),
    path("validate-email/", views.validate_email, name="validate_email"),
    ]
    


    학생 등록 ​​보기 기능을 구현하여 이 섹션을 마무리하겠습니다.

    from django.conf import settings
    ...
    from django.contrib.sites.shortcuts import get_current_site
    ...
    from . import tasks, utils
    from .forms import LoginForm, StudentRegistrationForm
    from .tokens import account_activation_token
    
    ...
    
    def student_signup(request):
        form = StudentRegistrationForm(request.POST or None)
        if request.method == "POST":
            post_data = request.POST.copy()
            email = post_data.get("email")
            username = post_data.get("username").replace("/", "")
            password = post_data.get("password1")
    
            if utils.is_valid_email(email):
                user = get_user_model().objects.create(email=post_data.get("email"))
    
            if utils.is_valid_password(password, user) and utils.is_valid_username(username):
                user.set_password(password)
                user.username = username
                user.first_name = post_data.get("first_name")
                user.last_name = post_data.get("last_name")
                user.level = post_data.get("level")
                user.gender = post_data.get("gender")
                user.is_active = False
                user.is_student = True
                user.save()
                subject = "Please Activate Your Student Account"
                ctx = {
                    "fullname": user.get_full_name(),
                    "domain": str(get_current_site(request)),
                    "uid": urlsafe_base64_encode(force_bytes(user.pk)),
                    "token": account_activation_token.make_token(user),
                }
    
                if settings.DEBUG:
                    tasks.send_email_message.delay(
                        subject=subject,
                        template_name="accounts/activation_request.txt",
                        user_id=user.id,
                        ctx=ctx,
                    )
                else:
                    tasks.send_email_message.delay(
                        subject=subject,
                        template_name="accounts/activation_request.html",
                        user_id=user.id,
                        ctx=ctx,
                    )
                raw_password = password
                user = authenticate(username=username, password=raw_password)
                return JsonResponse(
                    {
                        "success": True,
                        "msg": "Your account has been created! You need to verify your email address to be able to log in.",
                        "next": reverse("accounts:activation_sent"),
                    }
                )
            else:
                get_user_model().objects.get(email=post_data.get("email")).delete()
                return JsonResponse(
                    {
                        "success": False,
                        "msg": "Check your credentials: your password, username, and email! Ensure you adhere to all the specified measures.",
                    }
                )
        context = {"page_title": "Student registration", "form": form}
        return render(request, "accounts/student_signup.html", context)
    


    코드를 읽으면 몇 가지 어려움이 해결됩니다. 모든 필드가 이전에 규정된 규칙을 준수하는지 확인하기 위한 여러 개의 if 문입니다. tasks.pytoken.py 파일을 만들어야 합니다. 계속해서 그렇게하십시오.

    우리는 다음 부분에서 그것들의 유용성을 정의하고 이 소프트웨어의 구현을 진행할 것입니다.

    안녕!!!

    아웃트로



    이 기사를 즐겼습니다. contacting me for a job, something worthwhile or buying a coffee ☕을 고려하십시오.

    좋은 웹페이지 즐겨찾기