이번에는 로그인, 로그아웃 기능을 구현해볼 것이다.
Django에서 로그인, 로그아웃을 도와주는 앱은 django.contrib.auth이다. 이 앱은 프로젝트 생성 시 settings.py에 자동으로 추가된다.
INSTALLED_APPS = [
(... 생략 ...)
'django.contrib.auth',
(... 생략 ...)
]
1. common 앱 생성
먼저 로그인, 로그아웃 기능을 구현할 앱을 추가해줄 것이다. 현재까지 게시판 기능을 구현한 'notes' 앱만 구현했으므로, 이제는 '공통 기능을 가진 앱'을 추가하여 구현할 것이다.
터미널에 아래와 같이 입력해서 common 앱을 생성하자.
> django-admin startapp common
그리고 settings.py에 'common.apps.CommonConfig'을 추가하여 common앱을 등록하고,
common 앱의 urls.py 파일을 사용하기 위해 urls.py를 다음과 같이 수정한다.
urlpatterns = [
path('admin/', admin.site.urls),
path('pybo/', include('pybo.urls')),
path('common/', include('common.urls')),
]
그리고 common/urls.py 파일을 생성해서 다음과 같이 작성해준다.
app_name = 'common'
urlpatterns = [
]
2. 로그인
navbar.html에 "로그인" 링크를 아래와 같이 작성하여 로그인 화면으로 진입할 수 있도록 한다.
<ul class="navbar-nav">
<li class="nav-item ">
<a class="nav-link" href="{% url 'common:login' %}">로그인</a>
</li>
</ul>
이제 네비게이션바에서 "로그인" 버튼 클릭 시 로그인 화면이 연결될 수 있도록 urls.py에서 URL 매핑을 추가해야한다.
from django.urls import path
from django.contrib.auth import views as auth_views
app_name = 'common'
urlpatterns = [
path('login/', auth_views.LoginView.as_view(), name='login'),
]
그리고 django.contrib.auth 앱의 LoginView를 활용하면 로그인 뷰는 따로 만들 필요가 없다.
또 여기서 알아야할 점은, LoginView는 registration이라는 템플릿 디렉터리에서 login.html 파일을 찾는다. 그런데 우리는 common 앱에 로그인 기능을 구현할 것이므로 LoginView가 common 디렉터리의 템플릿을 참조할 수 있도록 common/urls.py를 아래와 같이 수정해주어야한다.
from django.urls import path
from django.contrib.auth import views as auth_views
app_name = 'common'
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name='common/login.html'), name='login'),
]
이렇게 설정을 완료했으면 이제 login.html 파일을 작성해주어야한다. common 템플릿 디렉터리에서 login.html 파일을 생성한 뒤 아래와 같이 작성한다.
{% extends "base.html" %}
{% block content %}
<div class="container my-3">
<form method="post" class="post-form" action="{% url 'common:login' %}">
{% csrf_token %}
{% include "form_errors.html" %}
<div class="form-group">
<label for="username">사용자ID</label>
<input type="text" class="form-control" name="username" id="username"
value="{{ form.username.value|default_if_none:'' }}">
</div>
<div class="form-group">
<label for="password">비밀번호</label>
<input type="password" class="form-control" name="password" id="password"
value="{{ form.password.value|default_if_none:'' }}">
</div>
<button type="submit" class="btn btn-primary">로그인</button>
</form>
</div>
{% endblock %}
사용자 id를 입력하는 username과 비밀번호를 입력하는 password 항목은 django.contrib.auth 앱의 필수 요구항목이다. 그리고 include 태그로 포함된 form_errors.html을 또 추가로 작성해보자. 아래 코드의 경우 로그인 실패 시 로그인이 왜 실패했는지 알려주는 기능을 한다.
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %} <!-- 필드 오류를 출력한다. -->
<div class="alert alert-danger">
<strong>{{ field.label }}</strong>
{{ error }}
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %} <!-- 넌필드 오류를 출력한다. -->
<div class="alert alert-danger">
<strong>{{ error }}</strong>
</div>
{% endfor %}
{% endif %}
폼 오류는 크게 두가지로 나눌 수 있다.
1. 필드 오류(field.errors): 사용자가 입력한 필드 값에 대한 오류로 값이 누락되었거나 필드의 형식이 일치하지 않는 경우에 발생하는 오류
2. 넌필드 오류(form.non_field_errors): 필드의 값과는 상관없이 다른 이유로 발생하는 오류
이제 로그인 페이지를 들어가서 비밀번호를 입력하지 않고 로그인 버튼을 눌러본다. 아래와 같이 "비밀번호는 필수 항목입니다."라고 오류 메세지가 잘 표시되는 것을 볼 수 있다.
3. 로그인 후 페이지 이동 설정
django.contrib.auth 패키지는 로그인이 성공하면 디폴트로 /accounts/profile/ URL로 이동하게 되어있다.
하지만 이것은 우리의 목적과 맞지 않으므로 / 페이지로 이동할 수 있도록 수정할 것이다.
settings.py 파일에서 아래와 같이 LOGIN_REDIRECT_URL을 추가하면 된다.
# 로그인 성공후 이동하는 URL
LOGIN_REDIRECT_URL = '/'
이제 로그인 후 페이지 이동이 잘 작동한다.
4. 로그아웃 기능 구현
로그인에 성공했지만, 네비게이션 바에 여전히 "로그인"이라고 뜨는 것을 볼 수 있다. 로그인 후에는 "로그아웃"이 뜨도록 수정해야한다.
narbar.html을 아래와 같이 수정한다.
{% if user.is_authenticated %}은 현재 사용자가 로그인 되었는지 판별한다.
<li class="nav-item">
{% if user.is_authenticated %}
<a class="nav-link" href="{% url 'common:logout' %}">{{ user.username }} (로그아웃)</a>
{% else %}
<a class="nav-link" href="{% url 'common:login' %}">로그인</a>
{% endif %}
</li>
그러면 이제 URL 매핑을 해주어야한다. common/urls.py를 아래와 같이 수정한다.
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name='common/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]
그리고 로그아웃 시 리다이렉트할 페이지도 settings.py에 추가한다.
# 로그아웃시 이동하는 URL
LOGOUT_REDIRECT_URL = '/'
5. 결과 확인
이제 로그인을 하면 아래와 같이 네비게이션바에 "로그아웃" 버튼이 뜨고, 로그아웃 버튼 클릭 시 리다이렉트 되도록 설정한 페이지가 잘 뜨는 것을 볼 수 있다.
'Web > Django' 카테고리의 다른 글
장고(Django) 회원가입 페이지 구현하기, django.contrib.auth 활용 (0) | 2021.08.07 |
---|---|
장고(Django) 템플릿 필터 생성 및 적용하기 (0) | 2021.08.04 |
장고(Django) Paginator을 활용하여 페이징 기능 구현하기 (4) | 2021.08.04 |
장고(Django) GET과 POST를 활용하여 폼(Form) 작업하기 (0) | 2021.08.03 |
Django(장고) static 디렉터리와 템플릿 상속 및 include 태그 사용 (0) | 2021.08.03 |