<django> login & logout 구현하기

이지혜·2021년 3월 22일
2

로그인, 로그아웃을 구현한 코드를 보며 django의 사용자 인증 및 권한 기능을 학습한다.

📌 accouts app 아래의 urls.py

from django.urls import path
from . import views

app_name = 'accounts'

urlpatterns = [
    # 세션에 관한 Create, delete
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
]

📌 Login : views.py

로그인에서 알아두어야 할 기능 3

  • AuthenticationForm : 로그인 기능을 수행하는 Form

  • login() : 사용자의 id를 session에 저장. request 객체, user 객체를 인자로 받는다.

  • is_authenticated : User class의 속성. 사용자가 인증되었는지 확인하는 방법이다.
    User에 항상 True이며, AnonymousUser에 대해서만 항상 False.
    단, 이것은 권한과는 관련이 없으며 사용자가 활성화 상태이거나 유효한 세션을 가지고 있는지도 확인하지 않는다.

from django.shortcuts import render, redirect
# 세션을 create 하기 위해 import, login 함수랑 이름 겹치면 안돼서 as로 호출
from django.contrib.auth import login as auth_login
from django.contrib.auth.forms import AuthenticationForm

def login(request):
    # 로그인이 되어있다면 아래 함수를 수행하기에 적합하지 않으므로 바로 redirect 한다.
    if request.user.is_authenticated:
        return redirect('articles:index')

    if request.method == 'POST':
    	# 첫번째 인자로 request 를 받아야 한다.
        form = AuthenticationForm(request, request.POST)
        if form.is_valid():
            # 유효성 검사를 통과하면 세션을 create 해야 함 -> login()
            auth_login(request, form.get_user())
            # url 에 next 가 있을 때랑 없을때 결과가 다름
            return redirect(request.GET.get('next') or 'articles:index')
    else:
    	# 로그인에 필요한 빈 종이를 생성해서 lognin.html 에 전달
        form = AuthenticationForm()
    context = {
        'form': form,
    }
    return render(request, 'accounts/login.html', context)

return redirect(request.GET.get('next') or 'articles:index')

로그인 하지 않은 상태에서 회원만 가능한 기능(ex: 게시물 수정하기)을 시도하면 로그인 페이지가 뜬다.

이 때 로그인을 한다면, 바로 next 뒤에 나오는 경로로 이동할 것이다.
즉, next 파라미터가 있다면 해당 경로로 redirect 하고 아니라면 articles:index 로 redirect. (단축평가)


📌 Login : login.html

{% extends 'base.html' %}

{% block content %}
<h1>로그인</h1>
<form action="" method="POST">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit">
</form>
{% endblock content %}

✅ form의 action 이 생략되면 현재 위치한 url 주소로 요청된다.
next 파라미터가 붙은 url로 요청보내려면 action 을 생략해야 함 (django 제공)


📌 login required decorator

login required decorator 를 사용한다면 게시물 작성, 게시물 수정 등 기능에서 로그인하지 않은 유저는 접근하지 못하게 할 수 있다.

  • 사용자가 로그인 했는지 확인하는 view를 위한 데코레이터
  • 로그인 하지 않은 사용자를 settings.LOGIN_URL에 설정된 경로로 redirect 시킴
  • LONIN_URL의 기본 값은 '/accounts/login/' (계정관련 app은 accounts 로 만들어주는 것이 좋다.)
  • 로그인 된 사용자의 경우 해당 view 함수를 실행

대표적으로 게시물을 작성하는 함수 create는 로그인한 사용자만 가능하게 설정한다.
이 외에도 게시물을 수정하는 update 함수나, 게시물의 자세한 내용을 보는 detail 함수도 로그인한 사용자만 접근하게 할 수도 있다.(인스타그램도 로그인한 사람만 볼 수 있다.)

from django.contrib.auth.decorators import login_required

@login_required 
@require_http_methods(['GET', 'POST'])
def create(request):
    pass

✅ 하지만 게시물을 삭제하는 delete 함수에는 login required 데코레이터를 사용할 수 없다. (로직 상 맞지 않기 때문) 대신 is_authenticated를 쓸 수 있다.

@require_POST
def delete(request, pk):
    if request.user.is_authenticated:
        article = get_object_or_404(Article, pk=pk)
        article.delete()
        return redirect('articles:index')

📌 Logout : views.py

로그아웃에서 알아두어야 할 기능

  • require_POST : DB를 건드리면 안되므로 POST 방식으로 요청받을 때만 함수 수행

  • logout() : Request 객체를 받으며 return이 없다. 현재 요청에 대한 db의 세션 데이터를 삭제하고 클라이언트 쿠키에서도 sessionid를 삭제한다. (세션을 delete 하는 로직과 같음)

from django.views.decorators.http import require_POST
from django.contrib.auth import logout as auth_logout

@require_POST
def logout(request):
    auth_logout(request)
    return redirect('articles:index')
profile
이제는 이졔

0개의 댓글