📝

인증

참고문헌

  • 공식문서 : User의 기본 object
  • 공식문서 : User model에 모든 API

인증이란?

인증(Authentication)이란 쉽게 말해 유저의 로그인을 의미합니다. 로그인을 시도하는 유저가 우리 사이트에 가입한 유저가 맞는지 아이디와 비밀번호를 통해 확인하는 과정입니다.
Django는 인증을 통해 특정 페이지에 대한 권한을 부여할 수 있습니다.

User 모델

django에는 미리 만들어진 User 모델이 있습니다. settings.pyINSTALLED_APPS 리스트를 보시면 django.contrib.auth 라는 앱이 기본적으로 들어가 있을 것입니다.
INSTALLED_APPS = [ 'main', 'a', 'b', 'c', 'd', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
django가 기본적으로 가지고 있는 인증을 담당하는 앱으로 여기에 User 모델이 작성되어 있습니다. 우리는 이것을 가지고 쉽게 유저 인증을 구현할 수 있습니다. 그러므로 따로 User 모델을 작성할 필요는 없습니다.
여기에는 id, username, first_name, last_name, email, date_joined(가입한 날짜), password, last_login(마지막으로 로그인한 날짜) 등이 정의되어 있습니다. 자세한 내용은 공식 문서를 참고해주세요.

회원 가입

Built-in class-based view 중 CreateView를 이용하여 쉽게 구현이 가능합니다.
from django.contrib.auth import get_user_model from django.contrib.auth.forms import UserCreationForm from django.views.generic.edit import CreateView class SignupView(CreateView): template_name = 'signup.html' form_class = UserCreationForm model = get_user_model() def get_success_url(self): return '/dd/login/'
dd/views.py
  • template_name : 로그인 페이지로 사용할 html 템플릿
  • form_class : 폼으로 사용할 클래스. 여기서는 django의 auth앱에 미리 구현된 UserCreationForm을 사용합니다.
  • model : 해당 CreationView로 생성할 모델
  • get_success_url() : 생성 성공하면 어느 URL로 이동할 것이지 설정
 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>회원 가입</h1> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="가입하기"> </form> </body> </html>
dd/templates/signup.html
 
notion imagenotion image

로그인

로그인은 더 간단하게 구현할 수 있습니다. auth 앱 안에 LoginView가 이미 구현되어 있기 때문입니다.
from django.contrib.auth.views import LoginView as _LoginView class LoginView(_LoginView): template_name = "login.html"
dd/views.py
 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>로그인</h1> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="로그인"> </form> <a href="/dd/">홈으로</a> <a href="/dd/signup/">회원가입</a> </body> </html>
dd/templates/login.html
 
notion imagenotion image
 
로그인 구현시에는 특별히 settings.py에 LOGIN_REDIRECT_URL 값을 정해주어야 합니다. 이 값은 로그인 성공 후 이동할 페이지를 결정합니다.
LOGIN_REDIRECT_URL = '/dd/'
설정하지 않을 시 기본 값은 /accounts/profile/ 입니다.

로그아웃

로그아웃도 로그인과 마찬가지로 auth 앱에 LogoutView가 구현되어 있습니다.
class LogoutView(_LogoutView): template_name = "logout.html"
dd/views.py
  • template_name : 로그아웃 후에 보여질 템플릿 명
 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h3>로그아웃 되었습니다.</h3> <a href="/dd/">홈으로</a> <a href="/dd/login/">로그인 하기</a> </body> </html>
dd/templates/logout.html
 
notion imagenotion image

게시물 작성자 입력

(저자)1:N(게시물)의 관계는 ForeignKey로 표현합니다.
from django.contrib.auth.models import User # ... 중략 ... class Blog(models.Model): # ... 중략 ... author = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)

로그인 사용자 권한 설정

다음과 같은 코드로 로그인 사용자의 페이지 접근 권한을 제어할 수 있습니다. 보다 세부적인 접근 권한 제어는 공식 문서를 참고해주세요.
from django.contrib.auth.decorators import login_required @login_required def my_view(request): ...

소셜로그인을 위한 Django-allauth

django-allauth 라이브러리를 사용하면 소셜로그인을 쉽게 구현할 수 있습니다. 자세한 내용은 아래 문서를 참고해주세요.
 

 

최종 코드

from d.views import indexD, SignupView, LoginView, LogoutView # .. 중략 .. urlpatterns = [ # .. 중략 .. path('dd/', indexD), path('dd/signup/', SignupView.as_view()), path('dd/login/', LoginView.as_view()), path('dd/logout/', LogoutView.as_view()), ] urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
from django.shortcuts import render from django.contrib.auth import get_user_model from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.views import LoginView as _LoginView, LogoutView as _LogoutView from django.views.generic.detail import DetailView from django.views.generic.edit import CreateView def indexD(request): return render(request, 'indexD.html') class SignupView(CreateView): template_name = 'signup.html' form_class = UserCreationForm model = get_user_model() def get_success_url(self): return '/dd/login/' class LoginView(_LoginView): template_name = "login.html" class LogoutView(_LogoutView): template_name = "logout.html" class Profile(DetailView): pass
views.py
 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <h1>hello world D</h1> {% if user.is_authenticated %} <p>로그인 된 유저 : {{ user }}</p> <a href="/dd/logout/">로그아웃</a> {% else %} <a href="/dd/signup/">회원 가입</a> <a href="/dd/login/">로그인</a> {% endif %} </body> </html>
indexD.html
 
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>로그인</h1> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="로그인"> </form> <a href="/dd/">홈으로</a> <a href="/dd/signup/">회원가입</a> </body> </html>
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h3>로그아웃 되었습니다.</h3> <a href="/dd/">홈으로</a> <a href="/dd/login/">로그인 하기</a> </body> </html>
logout.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> .. 이 파일은 별도로 꾸미지 않습니다 .. </body> </html>
profile.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>회원 가입</h1> <form action="" method="post"> {% csrf_token %} {{ form.as_p }} <input type="submit" value="가입하기"> </form> </body> </html>
signup.html