Django의 쇼핑백 사용(섹션 3) - 사용자 인증

33269 단어 webdevdjangopython

소개하다.



previous blog에서 우리는 템플릿 계승과 정적 파일에 어떻게 서비스를 제공하는지 배웠다.우리도 템플릿을 복구했다.이 블로그에서, 우리는 어떻게 우리의 웹 응용 프로그램에서 사용자를 검증하는지 보게 될 것이다.
간단하게 보기 위해서, 우리는 사용자 정의 신분 검증을 사용하지 않을 것이다.반대로 우리는 Django의 사용자 모델을 사용할 것이다. 이것은 우리의 임무를 더욱 간단하게 할 것이다.우리 시작합시다!

경고


다음 장에서, 우리는 보통 폼이나 다른 유형의 사용자 입력을 처리한 후에 사용자에게 일회성 알림 메시지 ("플래시 메시지"라고도 부른다) 를 표시해야 한다.이를 위해 Django는 익명과 인증을 받은 사용자에게 쿠키와 세션 기반 메시지 전달에 대한 전면적인 지원을 제공합니다.메시지 프레임워크는 요청을 임시로 저장하고 다음 요청 (보통 다음 요청) 에서 메시지를 검색할 수 있도록 합니다.각 메시지에는 우선 순위를 지정하는 특정 level 태그가 있습니다(예: info, warning 또는 error).
Django 템플릿 언어에는 include 태그가 있습니다.include은 템플릿을 불러오고 현재 위아래 문장으로 표시합니다.템플릿에 다른 템플릿을 포함시키는 방법입니다.템플릿 이름은 변수 또는 하드 인코딩(따옴표 포함) 문자열 또는 단일 따옴표 또는 더블 따옴표일 수 있습니다.partials 폴더에는 templates 폴더를, partials 폴더에는 alerts.html 파일을 만들고 다음 코드를 추가합니다.
{% if messages %} 
    {% for message in messages %} 
        {% if message.tags == 'error' %}
            <div class="alert alert-danger alert-dismissible fade show" role="alert">
            {{message}}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        {% else %}
            <div class="alert alert-{{message.tags}} alert-dismissible fade show" role="alert">
            {{message}}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
            </div>
        {% endif %}
    {% endfor %} 
{% endif %}

경고에는 Bootstrap dismissable alerts을 사용합니다.보기 함수에서 전달된 메시지를 반복해서 분류에 따라 표시하고 있습니다.메시지가 하나라도 messages 서열을 교체해야 합니다. 그렇지 않으면 메시지 저장소가 다음 요청을 제거하지 않기 때문입니다.우리는if조건을 사용하여 message.tag의 오류 여부를 검사한 다음에 위험 경보를 표시합니다. 그렇지 않으면 우리는 message.tag을 사용하여 직접 경보를 표시합니다.안내에 위험한 종류가 있지만 Django에 잘못된 표시가 있기 때문이다.

새 사용자 등록


우리가 하고 싶은 첫 번째 일은 새로운 사용자를 등록하는 것이다.사용자가 등록 페이지에 들어갈 때마다 사용자 이름과 비밀번호를 입력해야 한다.사용자 이름이 데이터베이스에 없으면 사용자가 생성되어 로그인 페이지로 리디렉션됩니다.동일한 사용자 이름을 가진 사용자가 이미 있으면 오류 메시지가 표시됩니다.
인증 관련 작업이므로 accounts/views.py 파일을 열고 다음 코드를 추가합니다.
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.models import User

def signup(request):
    if request.user.is_authenticated:
        return redirect('index')
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username and password:
            try:
                User.objects.get(username=username)
                messages.error(request, 'User already exists')
            except User.DoesNotExist:
                User.objects.create_user(username=username, password=password)
                messages.success(request, 'Signup success')
                return redirect('signin')
        messages.error(request, "Username or Password is missing!")
    return render(request, 'signup.html')
위의 스크립트에서, 우리는 먼저 사용자가 인증을 받았는지 확인합니다.만약 그렇다면, 우리는 그것을 색인 페이지로 다시 정할 것입니다.그리고 우리는 사용자가 사용자 이름과 비밀번호를 입력했는지 검사했다.만약 없다면, 우리는 사용자 이름이나 비밀번호가 부족하다는 오류 메시지를 보일 것입니다.그리고 사용자가 데이터베이스에 존재하는지 확인합니다.만약 그렇다면, 사용자가 이미 존재한다는 오류가 다시 한 번 번쩍입니다.그렇지 않으면 사용자는 로그인 페이지로 만들어지고 다시 지정됩니다.
이제 보기 함수에 대한 URL 라우트를 accounts/urls.py 파일에 만들어야 합니다.
from django.urls import path

from accounts.views import signup

urlpatterns = [
    path('signup', signup, name='signup'),
]

이제 등록 기능을 처리하기 위한 보기 기능이 생겼고 URL 루트가 추가되었습니다. 등록표를 변경할 준비가 되어 있습니다.templates/signup.html을 열고 다음 코드를 추가합니다.
{% extends "base.html" %}{% load static %} {% block title %} Sign Up {% endblock title %} 

{% block custom_head %}
<link rel="stylesheet" href="{% static 'css/signin.css' %}" />
{% endblock custom_head %} 

{% block content %}
<body class="text-center">
  <main class="form-signin">
    <form method="POST" action="{% url 'signup' %}">
      {% csrf_token %}

      <h1 class="h3 mb-3 fw-normal">Please sign up</h1>
      {% include 'partials/alerts.html' %}
      <div class="form-floating mt-2">
        <input
          type="text"
          class="form-control"
          id="floatingInput"
          name="username"
          placeholder="johndoe"
        />
        <label for="floatingInput">Username</label>
      </div>
      <div class="form-floating mt-2">
        <input
          type="password"
          class="form-control"
          id="floatingPassword"
          name="password"
          placeholder="Password"
        />
        <label for="floatingPassword">Password</label>
      </div>

      <button class="w-100 btn btn-lg btn-primary" type="submit">
        Sign up
      </button>
      <p class="mt-3">
        Already Registered? <a href="{% url 'signin' %}">Sign in now</a>
      </p>
    </form>
  </main>
</body>
{% endblock content %}

우리가 하고 있는 첫 번째 변경 사항은 탭입니다.양식 메서드는 POST으로 설정되어 있으며 작업 URL은 우리가 방금 만든 등록 경로입니다.또한 등록된 에 로그인 페이지의 URL을 추가하고 있습니까?줄을 서다.우리는 아직 이 노선을 창설하지 않았다.

사용자 로그인


다음에 로그인 기능을 만들어야 합니다.계정/보기에서py 파일에 다음 보기 함수를 추가합니다.
from django.contrib.auth import authenticate, login

def signin(request):
    if request.user.is_authenticated:
        return redirect('index')

    redirect_url = request.GET.get('next')
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username and password:
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)
                if redirect_url:
                    return redirect(redirect_url)
                return redirect('index')
            else:
                messages.error(request, 'Incorrect username or password!')
                return redirect(f'/accounts/signin?next={redirect_url}')
        messages.error(request, "Username or Password is missing!")
    return render(request, 'signin.html')
이 보기 기능은 등록 기능과 매우 비슷하다.데이터베이스에 사용자가 있는지 확인하기 위해 authenticate 함수를 사용합니다.없으면 오류 메시지를 표시하고 사용자를 같은 로그인 페이지로 다시 지정합니다.사용자가 있는 경우 로그인합니다.그런 다음 URL에 다음 라우트가 있는지 확인합니다.만약 존재한다면, 우리는 사용자를 이 페이지로 다시 정할 것입니다. 그렇지 않으면 색인 페이지로 다시 정할 것입니다.다음 매개 변수는 사용자에게 어느 페이지로 방향을 바꿔야 하는지 알려 줍니다.
이제 이 함수의 URL을 accounts/urls.py 파일에 만듭니다.
from django.urls import path

from accounts.views import signin, signup

urlpatterns = [
    path('signup', signup, name='signup'),
    path('signin', signin, name='signin'),
]

마지막 변경 사항은 signin.html 파일에 있습니다.
{% extends "base.html" %}{% load static %} {% block title %} Sign In {% endblock title %} 

{% block custom_head %}
<link rel="stylesheet" href="{% static 'css/signin.css' %}" />
{% endblock custom_head %} 

{% block content %}
<body class="text-center">
  <main class="form-signin">
    <form method="POST" action="{% url 'signin' %}{% if request.GET.next %}?next={{request.GET.next}}{% endif %}">
      {% csrf_token %}

      <h1 class="h3 mb-3 fw-normal">Please sign in</h1>
      {% include 'partials/alerts.html' %}
      <div class="form-floating mt-2">
        <input
          type="text"
          class="form-control"
          id="floatingInput"
          name="username"
          placeholder="johndoe"
        />
        <label for="floatingInput">Username</label>
      </div>
      <div class="form-floating mt-2">
        <input
          type="password"
          class="form-control"
          id="floatingPassword"
          name="password"
          placeholder="Password"
        />
        <label for="floatingPassword">Password</label>
      </div>

      <button class="w-100 btn btn-lg btn-primary" type="submit">
        Sign in
      </button>
      <p class="mt-3">New user? <a href="{% url 'signup' %}">Sign up now</a></p>
    </form>
  </main>
</body>
{% endblock content %}

이곳의 모든 것은 매우 비슷하다.동작 URL은 약간 변경되었습니다.요청 URL에 다음 매개 변수가 있으면 작업 URL에 매개 변수를 추가합니다.

사용자 로그아웃


우리의 유일한 남은 것은 사용자를 취소하는 것이다.
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

@login_required
def signout(request):
    logout(request)
    messages.info(request, "Logged out!")
    return redirect('signin')

@login_required 장식기를 사용했기 때문에 인증을 받은 사용자만 로그아웃할 수 있습니다.URL에 이 보기 함수를 추가합니다.
from django.urls import path

from accounts.views import signin, signout, signup

urlpatterns = [
    path('signup', signup, name='signup'),
    path('signin', signin, name='signin'),
    path('signout', signout, name='signout'),
]

settings.py 파일에 다음 줄을 추가합니다.
LOGIN_URL = '/accounts/signin'
또한 색인 페이지에 로그아웃 단추를 추가해야 합니다.index.html 파일을 열고 다음을 추가합니다.
{% extends "base.html" %}{% load static %} {% block title %}View Bag{% endblock title %} 

{% block content %}
<body>
  <div class="container mt-5">
    <!-- top -->
    <div class="row">
      <div class="col-lg-6">
        <h1>View Grocery List</h1>
      </div>
      <div class="col-lg-6 float-right">
        <div class="row">
          <div class="col-lg-6">
            <!-- Date Filtering-->
            <input type="date" class="form-control" />
          </div>
          <div class="col-lg-4">
            <input type="submit" class="btn btn-danger" value="filter" />
          </div>
          <div class="col-lg-2">
            <p class="mt-1"><a href="{% url 'signout' %}">Log Out</a></p>
          </div>
        </div>
      </div>
    </div>
    <!-- // top -->
    <!-- Grocery Cards -->
    <div class="row mt-4">
      <!--- -->
      <!-- Loop This -->
      <div class="col-lg-4">
        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Tomato</h5>
            <h6 class="card-subtitle mb-2 text-muted">2 Pcs.</h6>
            <p class="text-success">BOUGHT</p>
          </div>
        </div>
      </div>
      <!-- // Loop -->
      <div class="col-lg-4">
        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Chicken</h5>
            <h6 class="card-subtitle mb-2 text-muted">2Kgs</h6>
            <p class="text-danger">NOT AVAILABLE</p>
          </div>
        </div>
      </div>

      <div class="col-lg-4">
        <div class="card">
          <div class="card-body">
            <h5 class="card-title">Posto</h5>
            <h6 class="card-subtitle mb-2 text-muted">50gms</h6>
            <p class="text-info">PENDING</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
{% endblock content %}

사용자 권한 부여


우리는 색인 페이지를 인증된 사용자만 사용할 수 있도록 할 것입니다.사용자가 인증을 통과하지 못하면 LOGIN_URL으로 리디렉션됩니다.
from django.shortcuts import render
from django.contrib.auth.decorators import login_required

# Create your views here.

@login_required
def index(request):
    return render(request, "index.html")

데이터베이스 마이그레이션


이제 데이터베이스 마이그레이션을 실행하기 위한 모든 작업이 완료되었습니다.
$ python manage.py makemigrations
$ python manage.py migrate 

프레젠테이션 비디오


데모 영상 보기:
결론
이 부분에서 우리는 사용자에 대해 어떻게 신분 검증을 하는지, 그리고 사용자가 일부 페이지에 접근하는 것을 제한하는 방법을 보았다.다음 섹션에서는 CRUD 작업을 검토합니다.기대해주세요!
현재 코드: https://github.com/ashutoshkrris/Grocery-Bag/tree/blog3

좋은 웹페이지 즐겨찾기