[Django] 로그인 / 로그아웃 기능 구현하기

문지은·2023년 4월 27일
0

Django 기초

목록 보기
11/14
post-thumbnail

🌱 인증과 권한

  • Django authentication system(인증 시스템)은 인증(Authentication)과 권한(Authorization) 부여를 함께 제공(처리)하며, 이러한 기능을 일반적으로 인증 시스템이라고 함
  • 필수 구성은 settings.py에 이미 포함되어 있으며 INSTALLED_APPS에서 확인 가능
    • django.contrib_auth
  • Authentication (인증) : 신원 확인, 사용자가 누구인지 확인 하는 것
  • Authorization (권한, 허가) : 권한 부여, 인증된 사용자가 수행할 수 있는 작업을 결정

Django 인증 시스템을 사용하여 로그인 / 로그아웃 기능을 구현하는 방법을 알아보자!


🌱 사전 설정

  • accounts app 생성 및 등록
    • auth와 관련된 경로나 키워드들을 Django 내부적으로 accounts라는 이름으로 사용하고 있기 때문에 되도록 accounts로 지정하는 것을 권장
    • 다른 이름으로 설정해도 되지만 나중에 추가 설정을 해야 할 일들이 생김
$ python manage.py startapp accounts
# settings.py

# Application definition

INSTALLED_APPS = [
    'articles',
    'accounts',
		...
]
  • url 분리 및 매핑
# accounts/urls.py

from django.urls import path
from . import views

app_name = 'accounts'

urlpatterns = [
    
]
# crud/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('articles/', include('articles.urls')),
    path('accounts/', include('accounts.urls'))
]

⭐️ Login

SessionCreate하는 과정

AuthenticationForm

  • 로그인을 위한 built-in form
    • 로그인 하고자 하는 사용자 정보를 입력 받음
    • 기본적으로 username과 password를 받아 데이터가 유효한지 검증
  • request를 첫번째 인자로 취함

로그인 페이지 작성

login()

  • login(request, user, backend=None)
  • 인증된 사용자를 로그인 시키는 로직으로 view 함수에서 사용됨
  • 현제 세션에 연결하려는 인증된 사용자가 있는 경우 사용
  • HttpRequest 객체와 User 객체 필요

get_user()

  • AuthenticationForm의 인스턴스 메서드
  • 유효성 검사를 통과했을 경우 로그인 한 사용자 객체를 반환

로그인 로직 작성

  • view 함수 login과의 충돌을 방지하기 위해 import한 login 함수 이름을 auth_login으로 변경해서 사용

url

# account/urls.py

from django.urls import path
from . import views

app_name = 'accounts'

urlpatterns = [
    path('login/', views.login, name='login')
]

view

# accounts/views.py

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

# Create your views here.
def login(request):
    if request.method == 'POST':
        # 로그인 처리를 해줌
        form = AuthenticationForm(request, request.POST)
        if form.is_valid():
            auth_login(request, form.get_user())
            return redirect('articles:index')
    else:
        # 비어있는 로그인 페이지 제공
        form = AuthenticationForm()
    context = {
        'form' : form
    }
    return render(request, 'accounts/login.html', context)

template

<!-- accounts/login.html -->

{% extends 'base.html' %}

{% block content %}
<h1>Login</h1>
<form action="{% url 'accounts:login' %}" method="POST">
    {% csrf_token %}
    {{form.as_p}}
    <input type="submit">
</form>
{% endblock content %}

로그인 링크 작성

  • base 템플릿에 로그인 페이지로 이동할 수 있는 하이퍼링크 작성
<!-- base.html -->

<body>
  <a href="{% url 'accounts:login' %}">로그인</a>
  <hr>
  {% block content %}
  {% endblock content %}
	...
</body>
</html

세션 데이터 확인하기

  • 로그인 후 개발자 도구와 DB에서 django로부터 발급받은 세션 확인
    • 로그인은 관리자 계정을 만든 후 진행
    • $ python manage.py createsuperuser
  1. django_session 테이블에서 확인

  1. 브라우저에서 확인
    개발자 도구 - Application - Cookies

현재 로그인 되어 있는 유저 정보 출력하기

템플릿에서 인증 관련 데이터를 출력하는 방법

<!-- base.html -->

<body>
  <div class="container">
    <h3>안녕하세요, {{user}} 님!</h3>
    <a href="{% url 'accounts:login' %}">로그인</a>
    {% block content %}
    {% endblock content %}
  <hr>
  </div>
</body>
</html>

context processors

  • 템플릿이 렌더링 될 때 호출 가능한 컨텍스트 데이터 목록
  • 작성된 컨텍스트 데이터는 기본적으로 템플릿에서 사용 가능한 변수로 포함됨
  • 즉, django에서 자주 사용하는 데이터 목록을 미리 템플릿에 로드 해 둔 것
  • 현재 user변수를 담당하는 프로세서는 django.contrib.auth.context_processors.auth
    → context 데이터 없이 user 변수 사용 가능 !!!
# settings.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

django.contrib.auth.context_processors.auth

  • 현재 로그인한 사용자를 나타내는 User 클래스의 인스턴스가 템플릿 변수 {{ user }}에 저장됨
  • 클라이언트가 로그인 하지 않은 경우 AnnoymousUser 클래스의 인스턴스로 생성

⭐️ Logout

SessionDelete 하는 과정

logout()

  • logout(request)
  • HttpRequest 객체를 인자로 받고 반환 값이 없음
  • 사용자가 로그인 하지 않은 경우 오류를 발생시키지 않음
  • 다음 2가지 일을 처리
    1. 현재 요청에 대한 session data를 DB에서 삭제
    2. 클라이언트의 쿠키에서도 sessionid를 삭제
    • 다른 사람이 동일한 웹 브라우저를 사용하여 로그인하고, 이전 사용자의 세션 데이터에 액세스하는 것을 방지하기 위함

로그아웃 로직 작성

url

# accounts/urls.py

from django.urls import path
from . import views

app_name = 'accounts'

urlpatterns = [
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
]

view

# accounts/views.py

from django.contrib.auth import logout as auth_logout

def logout(request):
    auth_logout(request)
    return redirect('articles:index')

template

<!-- base.html -->

<body>
  <div class="container">
    <h3>안녕하세요, {{user}} 님!</h3>
    <a href="{% url 'accounts:login' %}">로그인</a>
    <form action="{% url 'accounts:logout' %}" method="POST">
      {% csrf_token %}
      <input type="submit" value="Logout">
    </form>
    {% block content %}
    {% endblock content %}
  <hr>
  </div>
</body>
</html>

로그아웃 출력 확인 및 테스트

  • 로그아웃 버튼 출력 확인
  • 로그아웃 버튼을 눌렀을 때

📍 프로젝트 전체 코드 확인하기

https://github.com/mjieun0956/TIL/tree/master/Django/230322

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글