본문 바로가기

문돌이 존버/Django 스터디

DRF rest-auth, allauth 이메일 인증(email verification) 처리하기!

반응형

이메일 인증 관련 views.py 는 아래와 같이 작성합니다. 한 외국인의 깃허브를 먼저 발견했지만 알고보니 django allauth의 ConfirmEmailView를 그대로 사용한 것입니다. django allauth의 공식 코드는 여기를 참고해주세요. 이는 잠시 후 urls.py 에서 보게될 이메일 url을 확인하는 것과 관련되어 있습니다. rest-auth FAQ를 보더라도 email confirm 부분은 allauth의 탬플릿을 통해 오버라이딩해야 한다고 하네요. 

# views.py
from rest_framework.exceptions import NotFound
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import AllowAny
from allauth.account.models import EmailConfirmation, EmailConfirmationHMAC


class ConfirmEmailView(APIView):
    permission_classes = [AllowAny]

    def get(self, *args, **kwargs):
        self.object = confirmation = self.get_object()
        confirmation.confirm(self.request)
        # A React Router Route will handle the failure scenario
        return HttpResponseRedirect('/login/success/')

    def get_object(self, queryset=None):
        key = self.kwargs['key']
        email_confirmation = EmailConfirmationHMAC.from_key(key)
        if not email_confirmation:
            if queryset is None:
                queryset = self.get_queryset()
            try:
                email_confirmation = queryset.get(key=key.lower())
            except EmailConfirmation.DoesNotExist:
                # A React Router Route will handle the failure scenario
                return HttpResponseRedirect('/login/failure/')
        return email_confirmation

    def get_queryset(self):
        qs = EmailConfirmation.objects.all_valid()
        qs = qs.select_related("email_address__user")
        return qs

참고로 allauth.account.models 에서 임포트(import)한 EmailConfirmation과 EmailConfirmationHMAC에 해당하는 깃허브 코드는 여기를 참고해주세요. 

# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

EMAIL_HOST = 'smtp.gmail.com' # 메일 호스트 서버

EMAIL_PORT = '587' # gmail과 통신하는 포트
 
EMAIL_HOST_USER = '****@gmail.com' # 발신할 이메일

EMAIL_HOST_PASSWORD = '****' # 발신할 메일의 비밀번호

EMAIL_USE_TLS = True # TLS 보안 방법

DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

URL_FRONT = 'http://****' # 공개적인 웹페이지가 있다면 등록

ACCOUNT_CONFIRM_EMAIL_ON_GET = True # 유저가 받은 링크를 클릭하면 회원가입 완료되게끔
ACCOUNT_EMAIL_REQUIRED = True

ACCOUNT_EMAIL_VERIFICATION = "mandatory"
# ACCOUNT_EMAIL_VERIFICATION = "none"

EMAIL_CONFIRMATION_AUTHENTICATED_REDIRECT_URL = '/' # 사이트와 관련한 자동응답을 받을 이메일 주소,'webmaster@localhost'

ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 1

# 이메일에 자동으로 표시되는 사이트 정보
ACCOUNT_EMAIL_SUBJECT_PREFIX = "도전하는 문돌이 블로그"

SMTP gmail을 사용하기 위해선 아래로 접속하여 허용을 눌러줘야 합니다. 보안 문제가 있기 때문에 개인 이메일로 진행할 경우, 테스트성으로 잠깐만 하고 비밀번호를 변경할 것을 권장합니다. 

보안 수준이 낮은 앱 및 Google 계정 허용

중요한 부분을 빼먹을 뻔했네요.. urls.py 파일도 추가할 것이 있습니다.

# urls.py
from rest_auth.registration.views import VerifyEmailView, RegisterView
from rest_auth.views import (
    LoginView, LogoutView, PasswordChangeView,
    PasswordResetView, PasswordResetConfirmView
)

from accounts.views import ConfirmEmailView

urlpatterns = [
    path('admin/', admin.site.urls),

    # 로그인
    path('rest-auth/login', LoginView.as_view(), name='rest_login'),
    path('rest-auth/logout', LogoutView.as_view(), name='rest_logout'),
    path('rest-auth/password/change', PasswordChangeView.as_view(), name='rest_password_change'),

    # 회원가입
    path('rest-auth/registration', RegisterView.as_view(), name='rest_register'),
    #
    path('accounts/', include('allauth.urls')),
	
    # 이메일 관련 필요
    path('accounts/allauth/', include('allauth.urls')),
    # 유효한 이메일이 유저에게 전달
    re_path(r'^account-confirm-email/$', VerifyEmailView.as_view(), name='account_email_verification_sent'),
    # 유저가 클릭한 이메일(=링크) 확인
    re_path(r'^account-confirm-email/(?P<key>[-:\w]+)/$', ConfirmEmailView.as_view(), name='account_confirm_email'),
]

위에서 이메일 관련 필요한 url을 주의하시기 바랍니다. name이 중요한데요, (확실치는 않지만)'account_email_verfication_sent'와 'account_confirm_email'은 바꾸시면 안됩니다. django-rest-auth에서 이미 정한 이름이기 때문이죠. 관련 내용을 확인하시려면 홈페이지를 참고하세요. 

이후 장고를 실행하고 회원가입을 하면 아래와 같이 "Verification e-mail sent"라는 문구가 보일 것입니다. 

회원가입할 때 사용한 이메일로 들어가면 아래와 같이 메일 호스트 서버에서 보낸 이메일이 있습니다. 이메일에 적힌 링크를 누르면 회원가입이 최종적으로 완료됩니다. 

자, 이제 회원가입과 로그인 부분은 얼추 작업을 완성한 것 같습니다. 다음에는 회원 가입시 입력하는 정보를 db에 저장하고, 회원 정보 수정, 회원 탈퇴, 이메일 및 아이디 중복 확인까지 views.py 에서 작동시켜 보겠습니다. 

728x90
반응형