인증 기능

jurin·2021년 12월 14일
0

웹 개발 시 필수 기능인 인증 기능은 일반적으로 로그인 시 username/password를 인증하는 것 외에도 로그인한 사용자에 대한 권한 부여와 웹 요청에 따른 사용자 식별, 사용자별 세션 할당 및 관리 기능 등 세션 처리 기능까지 포함된다.

테이블 설계 - 장고 기본 기능 사용

장고에서 제공하는 User 테이블을 기본으로 사용한다.

  • User 테이블 구조

URL 설계 - 장고 기본 기능 사용

장고에서 제공하는 인증 기능은 URL과 뷰는 이미 개발되어 있고, 템플릿은 템플릿 파일명만 정해져 있으므로 그 템플릿 내용은 개발자가 코딩해야 한다.

다만 회원가입 기능은 장고에서 제공하지 않으므로 직접 코딩해준다.

아래 2개는 직접 개발해야 한다.

settings 설정

setitng.py 파일에 지정해야 하는 항목 3가지

  1. LOGIN_URL: 로그인이 필요해서 로그인 페이지로 리다이렉트시키고자 할 때 사용하는 URL로 login_required() 데코레이터를 사용해야 한다.
    default: /accounts/login/

  2. LOGIN_REDIRECT_URL: 장고의 LoginView 뷰는 로그인 처리가 성공한 후 next 파라미터로 지정한 URL로 리다이렉트 시킨다. next 파라미터가 지정되지 않으면 이 설정 항목에서 지정한 URL로 리다이렉트 시킨다.
    default: /accounts/profile/

  3. LOGOUT_REDIRECT_URL: 장고의 LogoutView 뷰는 로그아웃 처리가 성공한 후 next_page 속성으로 지정한 URL로 리다이렉트 시킨다. 없다면 이 설정 항목에서 지정한 URL로 리다이렉트 시킨다. 요청에 next 파라미터가 있으면 next에 지정한 URL이 next_page 속성으로 사용된다.

위 3가지 중 LOGIN_URL은 디폴트 값을 사용할 것이고, LOGOUT_REDIRECT_URL은 사용하지 않아도 되니까 LOGIN_REDIRECT_URL만 지정해준다.

LOGIN_REDIRECT_URL = '/'

또 폼을 장식하는 데 유용한 django-widget-tweaks 앱을 설치하고 등록한다.

  1. 설치
    pip install django-widget-tweaks

  2. settings.py 등록

    'widget_tweaks',

모델 코딩

인증 기능에 필요한 테이블은 장고에서 기본 제공하므로 코딩할 필요가 없다.

URLconf 코딩

인증에 필요한 URL은 장고에서 기본으로 제공하기 때문에 django.contrib.auth.urls 모듈을 include() 함수로 가져와서 사용하면 된다.

BookMarkApp/urls.py

    # 장고의 인증 URLconf를 가져와서 사용한다. 
    path('accounts/', include('django.contrib.auth.urls')),
    path('accounts/register/', UserCreateView.as_view(), name='register'),
    path('accounts/register/done/', UserCreateDoneTV.as_view(), name='register_done'),

뷰 코딩

LoginView 등 장고 auth 모듈에서 제공하는 뷰는 따로 코딩할 필요가 없고 가입 처리용 뷰 UserCreateView와 UserCreateDoneTV만 코딩해주면 된다.

BookMarkApp/views.py

템플릿 코딩

base.html

base.html에서 우상단 Username 영역을 수정해준다.

login.html

{{ next }} 변수는 /accounts/login/?next=/post/3/ 처럼 로그인 URL의 쿼리 문자열로 지정된다. 만일 URL에 next 쿼리 문자열이 없으면, settigns.LOGIN_REDIRECT_URL 항목에 지정된 URL이 사용되고, 이 항목도 지정되어 있지 않으면 디폴트로 /accounts/profile/ URL로 리다이렉트된다.

register.html

가입 화면, 즉 사용자 계정을 생성하는 화면을 보여준다.

{% extends 'base.html' %}
{% load widget_tweaks %}

{% block title %}register.html{% endblock %}

{% block content %}

    <h1>New User Registration</h1>
    <p class="font-italic">Please enter your username and password twice.</p>

    {% if form.errors %}
    <div class="alert alert-danger">
        <div class="font-weight-bold">Wrong! Please correct the error(s) below.</div>
        {{ form.errors }}
    </div>
    {% endif %}

    <form action="." method="post" class="card pt-3">
        {% csrf_token %}
        <div class="form-group row">
            {{ form.username|add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
            <div class="col-sm-5">
                {{ form.username|add_class:"form-control"|attr:"autofocus" }}
            </div>
        </div>
        <div class="form-group row">
            {{ form.password1|add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
            <div class="col-sm-5">
                {{ form.password1|add_class:"form-control" }}
            </div>
        </div>
        <div class="form-group row">
            {{ form.password2|add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
            <div class="col-sm-5">
                {{ form.password2|add_class:"form-control" }}
            </div>
        </div>

        <div class="form-group">
            <div class="offset-sm-2 col-sm-5">
                <input type="submit" value="Register" class="btn btn-info"/>
            </div>
        </div>

    </form>

{% endblock %}

사용자 계정을 생성하기 위해 비밀번호를 두 번 입력할 수 있도록 password1 및 password2 입력 요소가 있다는 점 정도만 빼면 login.html과 거의 같다.

한가지 중요한 차이점은 login.html 파일에서는 AuthenticationForm을 사용했지만 이번 register.html 파일의 form 변수는 UserCreationForm 객체라는 점이다. UserCreationForm 폼도 장고에서 기본으로 제공한다.

템플릿 파일에서 장고의 폼을 장식하려 할 때 django-widget-tweaks 앱을 사용하면 HTML 태그의 요소들을 직접 다룰 수 있어서 편리하다.

register_done.html

가입 처리가 성공한 후에 보여주는 화면

{% extends 'base.html' %}

{% block title %}register_done.html{% endblock %}

{% block content %}

    <h1>Registration Completed Successfully</h1>
    <br>

    <p>Thank you for registering.</p>

    <p class="font-italic"><a href="{% url 'login' %}">Log in again</a></p>

{% endblock %}

password_change_form.html

비밀번호를 변경하기 위한 화면

{% extends 'base.html' %}
{% load widget_tweaks%}

{% block title %}password_change_form.html{% endblock %}

{% block content %}

    <h1>{{ title }}</h1>
    <p class="font-italic">Please enter your old password for security's sake,
    and then enter your new password twice.</p>

    {% if form.errors %}
    <div class="alert alert-danger">
        <div class="font-weight-bold">Wrong! Please correct the error(s) below.</div>
        {{ form.errors }}
    </div>
    {% endif %}

    <form action="." method="post" class="card pt-3">
        {% csrf_token %}
        <div class="form-group row">
            {{ form.old_password|add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
            <div class="col-sm-5">
                {{ form.old_password|add_class:"form-control"|attr:"autofocus" }}
            </div>
        </div>
        <div class="form-group row">
            {{ form.new_password1|add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
            <div class="col-sm-5">
                {{ form.new_password1|add_class:"form-control" }}
            </div>
        </div>
        <div class="form-group row">
            {{ form.new_password2|add_label_class:"col-form-label col-sm-2 ml-3 font-weight-bold" }}
            <div class="col-sm-5">
                {{ form.new_password2|add_class:"form-control" }}
            </div>
        </div>

        <div class="form-group">
            <div class="offset-sm-2 col-sm-5">
                <input type="submit" value="Password change" class="btn btn-info"/>
            </div>
        </div>

    </form>


{% endblock %}
  • PasswordChangeView 뷰에서 title='Password change'라는 컨텍스 변수를 넘겨줌
  • form 변수는 장고에서 기본 제공하는 PasswordChangeForm 객체이다.

password_change_done.html

비밀번호 변경 처리가 성공한 후에 보여주는 화면

{% extends 'base.html' %}

{% block title %}password_change_done.html{% endblock %}

{% block content %}

    <h1>{{ title }}</h1>
    <br>

    <p>Your password was changed</p>

{% endblock %}

logged_out.html

로그아웃 처리가 성공한 후 나타나는 화면

{% extends 'base.html' %}

{% block title %}logged_out.html{% endblock %}

{% block content %}

    <h1>Logged out</h1>
    <br>

    <div>
        <i class="fas fa-quote-left"></i>
        <span class="h6">&ensp;Thanks for spending 
            your quality time with this web site today.&ensp;</span>
        <i class="fas fa-quote-right"></i>
    </div>

    <p class="font-italic"><a href="{% url 'login' %}">Log in again</a></p>

{% endblock %}





출처: Django로 배우는 파이썬 웹 프로그래밍(실전편) - 김석훈님

profile
anaooauc1236@naver.com

0개의 댓글