Django 로그인, 로그아웃 구현하기
2022. 2. 7. 13:32ㆍ강의 정리/Django 기초
반응형
장고(Django)를 배우기 시작한 입문자이시거나, 또는 배우고 싶은 생각이 있으신 분은 위 출처의 강의를 적극 추천드립니다!!!
로그인 구현하기
아이디 / 암호를 통한 로그인
#accounts/views.py
from django.contrib.auth.views import LoginView
login = LoginView.as_view(tempalte_name= "accounts/login_form.html")
- Django 클래스 뷰의 LoginView를 상속받습니다
https://github.com/django/django/blob/main/django/contrib/auth/views.py
class LoginView(SuccessURLAllowedHostsMixin, FormView):
"""
Display the login form and handle the login action.
"""
form_class = AuthenticationForm
authentication_form = None
next_page = None
redirect_field_name = REDIRECT_FIELD_NAME
template_name = 'registration/login.html'
redirect_authenticated_user = False
extra_context = None
@method_decorator(sensitive_post_parameters())
@method_decorator(csrf_protect)
@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
if self.redirect_authenticated_user and self.request.user.is_authenticated:
redirect_to = self.get_success_url()
if redirect_to == self.request.path:
raise ValueError(
"Redirection loop for authenticated user detected. Check that "
"your LOGIN_REDIRECT_URL doesn't point to a login page."
)
return HttpResponseRedirect(redirect_to)
return super().dispatch(request, *args, **kwargs)
def get_success_url(self):
return self.get_redirect_url() or self.get_default_redirect_url()
def get_redirect_url(self):
"""Return the user-originating redirect URL if it's safe."""
redirect_to = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, '')
)
url_is_safe = url_has_allowed_host_and_scheme(
url=redirect_to,
allowed_hosts=self.get_success_url_allowed_hosts(),
require_https=self.request.is_secure(),
)
return redirect_to if url_is_safe else ''
def get_default_redirect_url(self):
"""Return the default redirect URL."""
return resolve_url(self.next_page or settings.LOGIN_REDIRECT_URL)
def get_form_class(self):
return self.authentication_form or self.form_class
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def form_valid(self, form):
"""Security check complete. Log the user in."""
auth_login(self.request, form.get_user())
return HttpResponseRedirect(self.get_success_url())
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_site = get_current_site(self.request)
context.update({
self.redirect_field_name: self.get_redirect_url(),
'site': current_site,
'site_name': current_site.name,
**(self.extra_context or {})
})
return context
#accounts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/', views.signup, name='signup'),
# /accounts/login/ => settings.LOGIN_URL에 문자열로 지정되어 있음
path('login/', views.login, name='login'),
]
#프로젝트/templates/프로젝트/_form.html
{% load bootstrap4 %}
<div class="card">
{% if form_title %}
<div class="card-header">
{{ form_title }}
</div>
{% endif %}
<div class="card-body">
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">
Submit
</button>
{% endbuttons %}
</form>
</div>
</div>
- 만약 템플릿에 form_title이 지정되어있으면 카드의 헤더에 form_title을 노출 시킨다.
https://getbootstrap.kr/docs/5.0/components/card/
#accounts/templates/accounts/login_form.html
{% extends "accounts/layout.html" %}
{% load bootstrap4 %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-sm-6 offset-sm-3">
{% include "_form.html" with form_title="로그인" submit_label="로그인" %}
</div>
</div>
</div>
{% endblock %}
로그아웃
#accounts/views.py
from django.contrib.auth.views import LoginView, LogoutView, logout_then_login
#logout = LogoutView.as_view(template_name= "accounts/logout_form.html")
def logout(request):
messages.success(request, '로그아웃 되었습니다!')
return logout_then_login(request)
- Django 클래스 뷰의 LogoutView를 상속받습니다
https://github.com/django/django/blob/main/django/contrib/auth/views.py
class LogoutView(SuccessURLAllowedHostsMixin, TemplateView):
"""
Log out the user and display the 'You are logged out' message.
"""
next_page = None
redirect_field_name = REDIRECT_FIELD_NAME
template_name = 'registration/logged_out.html'
extra_context = None
@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
auth_logout(request)
next_page = self.get_next_page()
if next_page:
# Redirect to this page until the session has been cleared.
return HttpResponseRedirect(next_page)
return super().dispatch(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
"""Logout may be done via POST."""
return self.get(request, *args, **kwargs)
def get_next_page(self):
if self.next_page is not None:
next_page = resolve_url(self.next_page)
elif settings.LOGOUT_REDIRECT_URL:
next_page = resolve_url(settings.LOGOUT_REDIRECT_URL)
else:
next_page = self.next_page
if (self.redirect_field_name in self.request.POST or
self.redirect_field_name in self.request.GET):
next_page = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name)
)
url_is_safe = url_has_allowed_host_and_scheme(
url=next_page,
allowed_hosts=self.get_success_url_allowed_hosts(),
require_https=self.request.is_secure(),
)
# Security check -- Ensure the user-originating redirection URL is
# safe.
if not url_is_safe:
next_page = self.request.path
return next_page
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
current_site = get_current_site(self.request)
context.update({
'site': current_site,
'site_name': current_site.name,
'title': _('Logged out'),
'subtitle': None,
**(self.extra_context or {})
})
return context
- LogoutView에는 logout_then_login 함수가 존재한다.
- logout_then_login 함수는 유저가 로그아웃 할 경우에 바로 로그인 페이지로 redirect 해주는 함수이다.
def logout_then_login(request, login_url=None):
"""
Log out the user if they are logged in. Then redirect to the login page.
"""
login_url = resolve_url(login_url or settings.LOGIN_URL)
return LogoutView.as_view(next_page=login_url)(request)
#accounts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('logout/', views.logout, name='logout'),
]
회원 가입과 동시에 로그인
#accounts/views.py
from django.contrib.auth import login as auth_login
def signup(request):
"""
중략
"""
auth_login(request, signed_user)
"""
중략
"""
})
- Django auth에서 인증, 보안에 필요한 거의 모든 것들을 지원해주기 때문에 적극 활용하자
https://github.com/django/django/tree/main/django/contrib/auth
반응형
'강의 정리 > Django 기초' 카테고리의 다른 글
Django 유저 프로필 수정 (0) | 2022.02.08 |
---|---|
Django 프로필 디폴트 이미지 구현하기 (0) | 2022.02.07 |
Django 회원 가입 이메일 보내기 (1) | 2022.02.05 |
Django User 모델 커스텀 및 회원가입 구현 (0) | 2022.02.04 |
관계를 표현하는 모델 필드 #ManyToManyField (0) | 2022.01.03 |