django | 20. 로그인, 로그아웃 구현하기

21747 단어 djangodjango

장고는 로그인, 로그아웃을 쉽게 구현할 수 있도록 django.contrib.auth 앱을 제공한다. 이 앱은 장고 프로젝트 생성 시 settings.py에 자동으로 추가된다.
django.contrib.auth 관련 공식문서

앱 생성 후 초기 설정하기

로그인, 로그아웃은 home 앱에 구현해야 할까? 그렇지 않다. 하나의 웹 사이트에는 home과 같은 게시판 서비스외에도 블로그나 쇼핑몰과 같은 굵직한 단위의 앱들이 함께 있을 수 있기 때문에 공통으로 사용되는 기능인 로그인이나 로그아웃을 이 중의 하나의 앱에 종속시키는 것은 좋지 않기 때문이다. 이러한 이유로 'users' 앱을 만들어 구현할 것이다.

1. users 앱 생성하기

$ django-admin startapp users

2. 앱 등록하기

# settings.py

...
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    ...
    'home',
    'users',
]
...

3. urls.py에 url 연결하기


...
urlpatterns = [
  ...
  path('users/', include('users.urls')), # users>urls.py에서 관리할거야
]

/users/으로 시작하는 URL은 모두 users>urls.py 파일을 참조할 것이다.

4. user 앱의 urls.py 생성하기

urls.py 파일을 생성하고 아래의 코드를 작성한다.

# urls.py

from django.urls import path
from .views import * # user>views에서 모든 함수를 가져온다.

app_name = "users"
urlpatterns = [
]

로그인 구현하기

1. login.html 생성하기

users 앱에 templates>users 디렉토리를 생성한 후, 그 안에 login.html 파일을 만든다.

<!-- users>login.html -->

<h1>로그인 페이지야</h1>

2. 로그인 URL 연결하기

# 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 관련 공식문서

3. 로그인 템플릿 만들기

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'),
]

아래와 같이 잘 연결된다.

4. login.html 내용 구성하기

<!-- 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 %}

입력 항목 usernamepassword는 모두 django.contrib.auth 앱에서 요구하는 필수 항목이다.

5. form_errors.html 만들기

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 %}


6. 제대로 로그인해 보기

생성한 슈퍼 유저 계정으로 로그인을 해보면 아래와 같은 오류가 발생한다.

장고는 로그인을 하면 accounts/profile/ 라는 URL로 리다이렉트하는데, 지금 이 페이지가 존재하지 않아서 생긴 오류이다. 따라서 로그인 후 이동할 페이지를 등록해야 한다.

7. 로그인 성공 시 이동할 페이지 등록하기

장고는 accounts/profile/ URL로 리다이렉트하지만, 다른 URL로 이동하고 싶다. settings.py에서 마지막 줄에 코드를 추가한다.

# settings.py

# 로그인 성공 시 자동으로 이동할 URL
LOGIN_REDIRECT_URL = '/'

그러면 로그인 성공 시 / 페이지로 이동이 잘 된다.

8. 네브바에 연결하기

<!-- _navbar.html -->

<a href="{% url 'users:login' %}">로그인</a>



로그아웃 구현하기

1. 로그아웃 URL 연결하기

# 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'), # 코드 추가하기
]

2. 로그아웃 성공 시 이동할 페이지 등록하기

# settings.py

# 로그아웃 성공 시 자동으로 이동할 URL
LOGOUT_REDIRECT_URL = '/'

로그아웃에 성공하면 '/' 페이지로 리다이렉트할 것이다.

3. 네브바에 연결하기

<!-- _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에는 사용자에 대한 정보가 자동으로 들어가는 것인지는 잘 모르겠다. 필드로 따로 설정한 것은 없다.

사용자 관련 공식문서
새로운 로그인, 로그아웃 방법 : 공식문서

좋은 웹페이지 즐겨찾기