몰입공간

[Django] allauth로 email 로그인하기 (email login with allauth) 본문

Programming/Django

[Django] allauth로 email 로그인하기 (email login with allauth)

sahayana 2022. 1. 21. 16:08

 


#1.  Django All-auth

 

Django allauth는 장고 프레임워크로 구성된 웹 어플리케이션에서 유저 가입, 로그인 , 인증,  소셜로그인 등 account 영역의 전반적인 기능을 도와주는 패키지입니다.

 

여기서는 allauth 백엔드를 기반으로 유저 로그인을 ID가 아닌 e-mail로 처리하도록 하겠습니다.

allauth 설치 명령어는 다음과 같습니다.

$ pip install django-allauth

#2.  CustomUser 모델 구축하기

 

우선 계정관련 기능들을 처리할 accounts 앱을 따로 생성하고 settings 등록합니다.

$ django-admin startapp accounts
# settings.py
INSTALLED_APPS = [
    '''
    생략
    ''' 
    # local   
    'accounts',
]

 

이후 새로운 User모델을 구축합니다. 보통 내장된 User모델을 상속받아 커스터마이징하는 경우가 많은데,  

여기서는 AbstractUser모델을 상속받습니다.

 

AbstractUser 모델은 기본 User모델이 상속하는 장고의 기초 회원 모델입니다.

기본 User모델은 장고 내부에 미리 세팅이 되어있는 모델이라 변경에 제약이 많습니다.

따라서, AbstractModel을 상속받아 새로운 User모델을 구축하는 것이 좋습니다.

# accounts/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.

class CustomUser(AbstractUser):
	# 간단하게 nickname과 bio 필드를 추가로 넣었습니다.
    nickname = models.CharField(max_length=100, unique = True)
    bio = models.CharField(max_length=100, blank = True)

    def __str__(self):
        return self.email

 

❗ 참고로  AbstractModel을 상속받아 새로운 User모델을 커스터마이징하는 경우에 프로젝트를 생성하자 마자
설정하는 것이 좋습니다.

settings.py에서 AUTH_USER_MODEL 속성을 변경해야 하는데 기본적으로 모델을 수정하거나 추가하는 것이 아니라 새로운 사용자 객체를 추가하기 때문에 기존 프로젝트가 어느정도 진행되었다면,  DB안의 스키마를 꼬아버릴 가능성이 있습니다.


#3.  Form 생성하기

 

장고의 기존 모델인 UserCreationModelUserChangeForm을 상속받은 CustomForm을 생성합니다.

allauth는 기본적으로 로그인, 로그아웃 및 회원가입에 대한 default 폼을 제공하지만, 템플릿을 간단하게 제작하기
위해 따로 폼을 설정하여 적용합니다.

 

# accounts/forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import CustomUser

class CustomUserCreationForm(UserCreationForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'nickname', 'email')

class CustomUserChangeForm(UserChangeForm):

    class Meta:
        model = CustomUser
        fields = ('username', 'nickname', 'email')

#4.  Admin 페이지 수정하기

 

admin페이지에서 유저 생성과 프로필 수정을 도와줄 form을 지정하고 리스트에 바로 노출시킬 필드를 선택합니다. 

또한, 장고에서 기본적으로 사용하는 Group모델을 삭제하고 설정한 CustomModel만 쓰게 설정하였습니다.

 

# accounts/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import Group
from .forms import UserChangeForm, UserCreationForm
from .models import CustomUser
# Register your models here.

class CustomUserAdmin(UserAdmin):
    form = CustomUserChangeForm
    add_form = CustomUserCreationForm
    model = CustomUser
    list_display = ['username', 'email']

admin.site.register(CustomUser, CustomUserAdmin)
admin.site.unregister(Group)

add_form 속성은 새로운 회원정보를 생성할 때 사용할 폼을 지정하고, form 속성은 기존 회원 정보를 수정할 폼을 지정할 때 사용합니다.

 

Admin 페이지 설정


#5.  allauth 패키지 설치

 

allauth를 설치 후 settings에 다음과 같이 등록 후 migration을 진행합니다.

(참고로 DB충돌을 우려하여 기존의 스키마를 지우고 진행했습니다.)

# myblog/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.sites', # new

    # allauth
    'allauth',
    'allauth.account', 
    'allauth.socialaccount', 

    # local
    'tweet',
    'accounts',
]
'''
생략
'''
#allauth
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

AUTHENTICATION_BACKENDS = (
    # allauth와 상관없이 관리자는 기존 로그인 방식을 사용
    "django.contrib.auth.backends.ModelBackend",

    # 일반 유저는 allauth 인증 사용
    "allauth.account.auth_backends.AuthenticationBackend",
)

로그인 백엔드로 2가지 방법을 사용합니다.

일반 유저들은 allauth에 내장된 백엔드를 기반으로 email로 로그인을 합니다.

admin 페이지를 관리하는 superuser는 기존의 로그인 방식을 이용합니다.

 

settings에 다음과 같은 속성들을 추가로 설정합니다.

SITE_ID = 1

ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_SIGNUP_PASSWORD_ENTER_TWICE = True
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_UNIQUE_EMAIL = True

AUTH_USER_MODEL = 'accounts.CustomUser' 

LOGIN_REDIRECT_URL = '/'
ACCOUNT_LOGOUT_REDIRECT_URL = '/'

SITE_ID는 현재 관리하는 사이트의 데이터베이스 ID를 정수값으로 설정합니다.


만약 추가적으로 설정한 도메인과 settings.py가 있다면 그 도메인에는 다른 SITE_ID를 설정해야 장고가 각 사이트별 설정한 ID로 일치하는 DB를 참조할 수 있습니다.  (참조)

 

AUTH_USER_MODEL은 사용할 User 모델로 accounts앱의 CustomUser모델을 사용한다고 선언하는 속성입니다.

 

LOGIN_REDIRECT_URLACCOUNT_LOGOUT_REDIRECT_URL은 로그인 및 로그아웃을 성공적으로 마치고 redirect할 url주소를 설정하는 필드입니다.

 

나머지 속성들은 속성의 이름을 통해 기능을 충분히 유추할 수 있습니다.

 


#6.  URL 매핑

 

설정이 끝났으면 URL을 매핑하고  migration을 실행합니다.

# urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('accounts/', include('allauth.urls')),
]

allauth의 url은 이미 설정이 되어 있기 때문에 따로 설정할 필요가 없습니다.


#7.  템플릿 작성하기

 

templates의 하위 폴더로 account 폴더를 생성하고 login 및 signup 템플릿을 작성합니다.

 

# templates/account/login.html
{% extends "base.html" %}
{% block content %}

<div class="jumbotron">
    <h2>Log In</h2>
    <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Log In</button>
</form>
</div>

{% endblock %}
# templates/account/signup.html
{% extends "base.html" %}
{% block content %}

<div class="jumbotron">
    <h2>Sign Up</h2>
    <form method="post">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit">Sign Up</button>
    </form>
</div>

{% endblock %}

#8.  구동화면

 

# http://127.0.0.1:8000/accounts/login/

 

# http://127.0.0.1:8000/accounts/logout/

logout주소를 GET요청하면 위처럼 확인창이 뜨는데 settings에서 ACCOUNT_LOGOUT_ON_GET = True로 설정하면, 즉시 Logout이 됩니다.


#9.  참조

 


 

Comments