AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
Django의 기본 인증시스템은 django.contrib.auth.backends.ModelBackend 를 사용한다.
django session 기반의 인증 시스템이다.
jwt인증을 구현했다고 하더라도 admin 페이지에서는 계속 기본 인증시스템을 사용한다.
인터넷을 사용하다 보면 사이트마다 로그인하는 방식이 다르다.
- 이메일 형식의 아이디 입력.
- 일반 단어 형식의 아이디 입력.
- 소셜 로그인
- 기타..
처음에 회원가입을 할 때 아이디와 이메일을 모두 입력한다고 가정하자.
이때 아이디로도 로그인이 가능하고, 이메일로도 로그인이 가능하게 만들어보자.
## auth/authenticate.py
from django.contrib.auth import backends
from django.db.models import Q
from django.contrib.auth import get_user_model
from django.conf import settings
User = get_user_model()
class EmailorUsernameAuthBackend(backends.ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(User.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = User.objects.get(
Q(username__exact=username) |
Q(email__exact=username)
)
if user.check_password(password) and self.user_can_authenticate(user):
return user
except:
return None
try부분이 핵심이다.
입력받은 username과 일치하는 email또는 username을 가진 user를 가져온다.
해당 user의 password가 입력받은 password와 일치하면 user를 return한다.
아래 코드는 기존 django 인증 코드이다.
아래 코드를 기반으로 Email인증 backend를 커스텀 한 것이다.
## django.contrib.auth.backends.py
class ModelBackend(BaseBackend):
"""
Authenticates against settings.AUTH_USER_MODEL.
"""
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
def user_can_authenticate(self, user):
"""
Reject users with is_active=False. Custom user models that don't have
that attribute are allowed.
"""
is_active = getattr(user, 'is_active', None)
return is_active or is_active is None
'Back-End > Django' 카테고리의 다른 글
[Django] Serializer와 validate (TIP!) (0) | 2022.01.15 |
---|---|
[Django] DRF 구조 이해 #1 (APIView) (0) | 2022.01.11 |
[Django] DRF를 사용한 JWT Authentication #2 (0) | 2022.01.03 |
[Django] DRF를 사용한 JWT Authentication #1 (0) | 2022.01.03 |
[Django] Nested Serializer - Create (0) | 2021.12.31 |