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

nathan·2021년 7월 16일
1

Django

목록 보기
15/22
post-custom-banner

이번에는 장고에 내장되어 있는 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에서 받아온 usernamepassword의 유효성 검사를 진행한 후(is_valid()), usernamepassword라는 변수에 저장해준다.
    • form.cleaned_data란?
      • is_valid()가 True로 리턴되면 해당 데이터들은 form.cleaned_data라는 딕셔너리 값으로 넘어오게 된다.
    1. 해당 usernamepassword에 일치하는 User 모델이 있는지 확인한다.
    1. 만약 User가 존재한다면 (None이 아니라면), 로그인을 하고 home 화면으로 redirect 해준다.
    1. form.is_valid()에서 False가 리턴되거나 User가 존재하지 않으면 login 화면에 머무르게 된다.
    1. 만약 request.methodPOST가 아니라면 (form 데이터가 제출되는 사오항이 아니라면), AuthenticationFormform 변수에 담아 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
나는 날마다 모든 면에서 점점 더 나아지고 있다.
post-custom-banner

0개의 댓글