장고는 로그인, 로그아웃을 쉽게 구현할 수 있도록 django.contrib.auth
앱을 제공한다. 이 앱은 장고 프로젝트 생성 시 settings.py에 자동으로 추가된다.
django.contrib.auth 관련 공식문서
로그인, 로그아웃은 home 앱에 구현해야 할까? 그렇지 않다. 하나의 웹 사이트에는 home과 같은 게시판 서비스외에도 블로그나 쇼핑몰과 같은 굵직한 단위의 앱들이 함께 있을 수 있기 때문에 공통으로 사용되는 기능인 로그인이나 로그아웃을 이 중의 하나의 앱에 종속시키는 것은 좋지 않기 때문이다. 이러한 이유로 'users' 앱을 만들어 구현할 것이다.
$ django-admin startapp users
# settings.py
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
...
'home',
'users',
]
...
...
urlpatterns = [
...
path('users/', include('users.urls')), # users>urls.py에서 관리할거야
]
/users/
으로 시작하는 URL은 모두 users>urls.py 파일을 참조할 것이다.
urls.py 파일을 생성하고 아래의 코드를 작성한다.
# urls.py
from django.urls import path
from .views import * # user>views에서 모든 함수를 가져온다.
app_name = "users"
urlpatterns = [
]
users 앱에 templates>users 디렉토리를 생성한 후, 그 안에 login.html 파일을 만든다.
<!-- users>login.html -->
<h1>로그인 페이지야</h1>
# users>urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
app_name = "users"
urlpatterns = [
path('login/', auth_views.LoginView.as_view(), name='login'), # 수정해야하는 코드
# django.contrib.auth앱의 LoginView 클래스를 활용했으므로 별도의 views.py 파일 수정이 필요 없음
]
django.contrib.auth
앱을 사용할 것이므로 users>views.py 파일은 수정할 필요가 없다. 여기서는 django.contrib.auth
앱의 LoginView 클래스를 사용한다.
Authentication Views 관련 공식문서
user관련된 것은 users 앱에서 관리하기로 하였으므로 users/login
으로 들어가면 아래와 같은 에러가 발생한다.
registration/login.html
이 없다는 의미인데, 아래의 공식문서를 읽어보면 어떠한 문제인지 알 수 있다.
login템플릿 공식문서
LoginView는 registration이라는 템플릿 디렉토리에서 login.html 파일을 찾는다. 그런데 이 파일을 찾지 못해서 오류가 발생한 것이다. 지금 users앱에 구현할 것이므로 아래 사진과 같이 template_name='users/login.html'
으로 설정하면 registration 디렉토리가 아닌 users 디렉토리에서 login.html파일을 참조하게 된다.
아래와 같이 코드를 수정해준다.
# users>urls.py
...
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
]
아래와 같이 잘 연결된다.
<!-- users>login.html -->
{% extends 'base.html' %}
{% block content %}
<h1>로그인</h1>
<form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
<div>
<label>사용자 ID</label>
<input type="text" name="username" id="username">
</div>
<div>
<label>비밀번호</label>
<input type="text" name="password" id="password">
</div>
<button type="submit">로그인</button>
</form>
{% endblock %}
입력 항목 username
과 password
는 모두 django.contrib.auth
앱에서 요구하는 필수 항목이다.
users>form_errors.html 파일을 만든다.
<!-- users>form_errors.html -->
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<!-- 필드 오류를 출력한다. -->
<div>
<strong>{{ field.label }}</strong>
{{ error }}
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<!-- 넌필드 오류를 출력한다. -->
<div>
<strong>{{ error }}</strong>
</div>
{% endfor %}
{% endif %}
form_errors.html 파일은 로그인 실패 시 로그인이 실패한 원인을 알려 준다. 폼 오류에는 두 가지가 있는데
- 필드 오류(입력값이 누락되었거나 형식에 맞지 않음)
- 넌필드 오류(입력값과 관계없이 발생한 오류)
다 작성하면 login.html에 코드 한 줄을 추가한다.
<!-- users>login.html -->
...
<form method="post" action="{% url 'users:login' %}">
{% csrf_token %}
{% include 'users/form_errors.html' %} <!-- 코드 추가 -->
<div>
<label>사용자 ID</label>
...
</form>
{% endblock %}
생성한 슈퍼 유저 계정으로 로그인을 해보면 아래와 같은 오류가 발생한다.
장고는 로그인을 하면 accounts/profile/
라는 URL로 리다이렉트하는데, 지금 이 페이지가 존재하지 않아서 생긴 오류이다. 따라서 로그인 후 이동할 페이지를 등록해야 한다.
장고는 accounts/profile/
URL로 리다이렉트하지만, 다른 URL로 이동하고 싶다. settings.py
에서 마지막 줄에 코드를 추가한다.
# settings.py
# 로그인 성공 시 자동으로 이동할 URL
LOGIN_REDIRECT_URL = '/'
그러면 로그인 성공 시 / 페이지로 이동이 잘 된다.
<!-- _navbar.html -->
<a href="{% url 'users:login' %}">로그인</a>
# users>urls.py
from django.urls import path
from django.contrib.auth import views as auth_views
app_name = "users"
urlpatterns = [
path('login/', auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(), name='logout'), # 코드 추가하기
]
# settings.py
# 로그아웃 성공 시 자동으로 이동할 URL
LOGOUT_REDIRECT_URL = '/'
로그아웃에 성공하면 '/' 페이지로 리다이렉트할 것이다.
<!-- _navbar.html -->
{% if user.is_authenticated %}
<a href="{% url 'users:logout' %}">{{ user.username }}님 로그아웃</a>
<span>||</span>
{% else %}
<a href="{% url 'users:login' %}">로그인</a>
{% endif %}
{% if user.is_authenticated %}
는 현재 로그인 상태를 판별한다.
{{ user.username }}
는 로그인한 사용자명을 표시한다.
궁금궁금
user
에는 사용자에 대한 정보가 자동으로 들어가는 것인지는 잘 모르겠다. 필드로 따로 설정한 것은 없다.
글 많이 도움 됐습니다!! 혹시 회원가입 기능도 구현하셧나요?