Django

[Django] 로그인 & 로그아웃

김디니 2022. 10. 12. 23:51

로그인 상태 유지

우리가 웹 사이트에서 로그인을 하고 다른 페이지로 이동해도 로그인 상태가 유지된다. 

이는 서버와 클라이언트 간의 로그인 상태를 유지하기 위해 '쿠키와 세션'을 사용한다. 

 

쿠키

쿠키는 쉽게 말해서 사용자에게 주는 작은 데이터 조각이다. 

쿠키를 Key - Value의 데이터 형식으로 저장한다. 

동일한 서버에 똑같은 데이터를 보내줄 때 저장된 쿠키를 전송하는 것이다. 

즉, 쿠키는 다른 요청이지만 동일한 브라우저로부터 발생한 것인지 판단할 때 주로 사용한다. 

상태가 없는(stateless) HTTP에서 상태 정보를 관리하고, 사용자는 이로 인해 로그인 상태를 유지할 수 있다. 

  • 비연결지향(connectionless)
    • 서버는 요청에 대한 응답을 보내준 후 연결을 끊는다.
      • 네이버 메인 페이지가 대표적인 예이다. 
        • 우리가 네이버 메인 페이지를 보고 있을 때 네이버 서버는 메인 페이지를 응답하고 연결을 끊은 상태인 것이다. 
  • 무상태(stateless)
    • 연결을 끊는 순간 서버와 클라이언트 간의 통신이 끝나기 때문에 상태 정보가 유지되지 않는다. 
    • 서버와 클라이언트가 주고 받는 메세지들은 독립적이다. 

 

쿠키의 사용 목적

  • 세션을 관리하기 위해
    • 로그인, 아이디 자동완성, 공지 하루 안보기, 팝업 체크, 쇼핑몰의 장바구니 등
  • 개인화를 위해
    • 다크모드 등
  • 트래킹을 위해
    • 사용자 행동 기록 및 분석

 

세션 Session

사이트와 특정 브라우저 사이의 상태를 유지시켜준다. 

사용자가 서버에 접속하면 서버가 특정 session id를 발급하고, 클라이언트(사용자)는 session id를 쿠키에 저장한다.

그러므로, 사용자가 다시 동일한 서버에 접속하면 다시 session id를 저장한 쿠키를 서버에 전달한다.  

 

session id는 세션을 구별하기 위해 필요한 것이며 쿠키에는 session id만 저장한다. 

 

 

로그인 Login

AuthenticationForm

로그인 기능을 위해 Django에 내장되어 있는 form이다. 

  • 로그인을 위해 사용자 정보를 입력 받는다. (username, password, email, etc)
  • ModelForm이 아닌 일반 Form을 상속받고 있으며(이용하고 있으며), request를 첫번째 인자로 이용한다. 
# accounts/views.py

from django.contrib.auth.forms import AuthenticationForm

def login(request):
    if request.method == 'POST':
    	pass
    else:
    	form = AuthenticationForm()
    context = {
    	'form': form
    }
    return render(request, 'accounts/login.html', context)

views.py에서 AuthenticationForm을 불러온다. 

 

request를 통해 POST로 보내진 데이터를 받는다. 

즉, 로그인할 사용자의 username과 password를 받는 것이다. 

 

게시판을 만들 때 ModelForm 기반의 Create 로직과 동일하지만, ModelForm이 아닌 일반 Form으로 받기 때문에 필수 인자 구성이 다르다. 

즉, DB에 저장하는 것이 아닌 Session에 유저를 기록하는 함수를 호출한다. 

 

from django.contrib.auth import login as auth_login

def login(request):
    if request.method == 'POST':
    	form = AuthenticationForm(request, data=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)

내장되어 있는 login 기능을 불러온다. 

create 로직과 마찬가지고 request를 통해 POST로 받은 데이터를 유효성 검사 후 index로 페이지를 넘겨준다. 

 

 

Logout

요청한 유저에 대한 세션 정보를 삭제하는 개념이다. 

데이터베이스에서 session data를 삭제한다. 

또한, 클라이언트의 쿠키에서 session id를 삭제한다. 

 

# accounts/views.py

from django.contrib.auth import logout as auth_logout

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

로그인의 로직보다 훨~씬 간단하다!

Django에 내장되어 있는 logout을 불러온다. 

함수로 선언한 후 request를 받아온 후 index에 보내주는 것이다. 

 

물론, 내장되어 있는 logout 기능에는 DB에 해당 사용자의 session data를 삭제한 후 클라이언트 쿠키에서 session id를 삭제하는 로직이 있을 것이다!

 

 

페이지에서 로그인 로그아웃 상태를 다르게 보여주기

이를 위해서는 is_authenticated를 사용하면 된다!

 

<!-- base.html -->
{% if request.user.is_authenticated %}
    <h3>안녕하세요, {{ user }} 님</h3>
    <form action="{% url 'accounts:logout' %}" method="POST">
    {% csrf_token %}
    <input type="submit" value="Logout">
    </form>
    <a href="{% url 'accounts:update' %}">회원정보수정</a>
    </form>
{% else %}
    <a href="{% url 'accounts:login' %}">Login</a>
    <a href="{% url 'accounts:signup' %}">Signup</a>
{% endif %}

if문에 is_authenticated를 사용하여 

 

만약, user의 데이터가 인증되었다면 '안녕하세요, OOO님'을 띄우고, 

인증되지 않았다면 즉, 로그인 상태가 아니라면 로그인과 회원가입 버튼/링크 를 띄우는 것이다. 

 

# accounts/views.py
def login(request):
    if request.user.is_authenticated:
    	return redirect('articles:index')

이외에 로그인하지 않은 사용자는 볼 수 없는 게시글과 같은 페이지를 띄울 수 없게 할 수 있다!

 

from django.contrib.auth.decorators import login_required

@login_required
def create(request):
	pass

로그인 상태에서만 글을 작성/수정/삭제할 수 있도록 설정할 수 있다. 

'Django' 카테고리의 다른 글

[Django] ForeignKey - User 정보 가져오기  (0) 2022.10.19
[Django] 댓글 기능 구현  (0) 2022.10.18
[Django] 이미지 업로드 구현  (0) 2022.10.18
[이론] Django 개발 환경 설정 가이드  (0) 2022.09.21
[이론] 서버 기초  (0) 2022.09.21