Django - User모델을 이용한 Login, Logout

nathan·2021년 7월 16일

Django

목록 보기
15/22

이번에는 장고에 내장되어 있는 User 모델에 대해 알아보자.

User 모델은 왜 사용할까?

  • 인스타그램을 사용한다고 가정해보자
  • A와 B가 인스타그램 서버에 똑같이 home 화면을 요청한다고 했을 때, 서버는 같은 화면을 줘야할까?
  • 물론 그렇지 않다!

  • 서버는 A가 팔로우한 계정, B가 팔로우한 계정을 각각 파악하고 그에 맞는 화면을 뿌려주어야 한다.

  • 그리고 바로 이 User 모델을 사용해서 A와 B의 정보를 데이터베이스에 저장해 놓을 수 있다.

  • 뿐만아니라, User 모델 안에 저장된 사용자의 아이디와 비밀번호 정보를 통해서 로그인, 로그아웃 등의 기능도 구현할 수 있다.

  • 위 이미지는 이전에 Model에 대해 배웠을 때 접속했던 admin 페이지이다.
  • 여기엔 우리가 정의한 적이 없는 User 모델이 이미 정의되어 admin 페이지에 등록되어 있음을 알 수 있다.
  • 사실 장고는 사용자의 편의를 위해 User 모델을 미리 만들어 놓고 자유롭게 사용할 수 있도록 제공하고 있다.
  • 클릭해보면 이전에 python manage.py createsuperuser 명령어를 통해 만들었던 계정이 잘 저장되어 있다.

  • 그렇다면, 이제 User 모델을 이용해 회원가입과 로그인 기능을 구현해보도록 하자.


account app 생성

  • 우선 기존의 blog 앱과 분리하기 위해 account라는 앱을 하나 만들자.
python manage.py startapp account
  • 앱이 추가되었으니 settings.py에 새로운 앱을 알려준다.
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog',
    'account',
]

url 정의

  • account 앱의 url을 정의해주기 위해 urls.py를 account 앱 폴더 내에 정의한다.

account/urls.py

from django.urls import path
from . import views

app_name = 'account'

urlpatterns = [
   path('signup/', views.signup_view, name = 'signup'),
   path('login/', views.login_view, name= 'login'),
]
  • account 앱의 url을 include를 통해 연결하자.

modelproject/urls.py

from django.contrib import admin
from django.urls import path, include
from blog.views import *
# 만약 import blog.views <- 이렇게 되어 있는 분들은 그대로 진행!
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', home, name='home'), # 만약 blog.views.home <- 이렇게 되어 있는 분들은 그대로 진행!
    path('blog/', include('blog.urls')),
    path('account/', include('account.urls'))
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

templates 생성

  • account 폴더 내에 templates 폴더를 만들고 회원가입을 위한 signup.html, login.html 파일을 각각 만들자! (base.html을 상속해서 간단하게 틀만 만들어주도록 하자.)

  • login과 signup 페이지에서도 마찬가지로 ModelForm을 사용한다. 따라서 이 부분도 미리 html 코드에 써두자.

login.html

{% extends 'base.html' %}

{% block content %}

<h1>로그인 페이지</h1>
<form action="{% url 'account:login' %}" method="POST">
  {% csrf_token %}
  {{form.as_p}}
  <button type="submit">로그인</button>
</form>

{% endblock %}

signup.html

{% extends 'base.html' %}

{% block content %}

<h1>회원가입 페이지</h1>
<form action="{% url 'account:signup' %}" method="POST">
  {% csrf_token %}
  {{form.as_p}}
  <button type="submit">회원가입</button>
</form>
{% endblock %}

views.py와 urls.py에 html 연결

login view 구현

  • 장고가 기본적으로 제공하는 모듈들을 활용해 로그인을 먼저 구현해보자.

account/views.py

from django.shortcuts import render, redirect
from django.contrib.auth.forms import AuthenticationForm
from django.contrib import auth

# Create your views here.
def login_view(request):
  if request.method == 'POST':
    form = AuthenticationForm(request=request, data=request.POST)
    if form.is_valid():
      username = form.cleaned_data.get('username')
      password = form.cleaned_data.get('password')
      user = auth.authenticate(
        request=request,
        username=username,
        password=password
      )

      if user is not None:
        auth.login(request, user)
        return redirect('home')

    return redirect('account:login')
  
  else:
    form = AuthenticationForm()
    return render(request, 'login.html', {'form' : form})
    1. 기존 BlogForm을 사용했을 때와 마찬가지로 ModelForm을 사용할건데, 이번에는 직접 작성이 아닌 AuthenticationForm을 import하여 사용한다.
    1. AuthenticationForm에서 받아온 username과 password의 유효성 검사를 진행한 후(is_valid()), username과 password라는 변수에 저장해준다.
    • form.cleaned_data란?
      • is_valid()가 True로 리턴되면 해당 데이터들은 form.cleaned_data라는 딕셔너리 값으로 넘어오게 된다.
    1. 해당 username과 password에 일치하는 User 모델이 있는지 확인한다.
    1. 만약 User가 존재한다면 (None이 아니라면), 로그인을 하고 home 화면으로 redirect 해준다.
    1. form.is_valid()에서 False가 리턴되거나 User가 존재하지 않으면 login 화면에 머무르게 된다.
    1. 만약 request.method가 POST가 아니라면 (form 데이터가 제출되는 사오항이 아니라면), AuthenticationForm을 form 변수에 담아 login.html에 띄워준다.

로그인에 들어가면 다음과 같은 화면을 확인할 수 있다.

logout view 구현

def logout(request):
   auth.logout(request)
   return redirect('home')
  • views에 함수를 추가해줬으니 url에서도 해당 경로를 추가해야 한다.
  • 로그인을 하고 나면, 자신의 아이디가 NavBar에 뜨도록 수정하여, 로그인 여부를 확인할 수 있도록 해보자.

myproject/templates/base.html

{% if user.is_authenticated %}
<li class="nav-item">
  <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">{{request.user}}님 안녕하세요!</a>
</li>
<li class="nav-item">
  <a class="nav-link" href="{% url 'account:logout' %}" tabindex="-1" aria-disabled="true">로그아웃</a>
</li>

{% else %}

<li class="nav-item">
  <a class="nav-link" href="{% url 'account:login' %}" tabindex="-1" aria-disabled="true">로그인</a>
</li>
{% endif %}
  • NavBar를 이루고 있는 li 태그들 끝에 위 코드를 붙여 넣으면 된다.

  • 아직 signup을 만들지 않았지만 python manage.py createsuperuser를 통해 만든 admin 계정으로도 로그인이 가능하다.

    1. 로그아웃 된 상태
    1. 로그인 된 상태

로그인 여부에 따라 값이 다른 화면을 출력해주는 것을 확인할 수 있다.

profile
나는 날마다 모든 면에서 점점 더 나아지고 있다.

0개의 댓글