[Django] 이메일 인증하기 (+이메일 템플릿)

김재연·2022년 7월 22일
2

Watti

목록 보기
8/10
post-thumbnail
post-custom-banner

dj-rest-auth의 편리함에 감동먹음.. 개쩐다!!!!

인증 이메일 보내기

- settings.py

# settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

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

EMAIL_PORT = '587' # gmail과 통신하는 포트
 
EMAIL_HOST_USER = os.environ.get("EMAIL_HOST_USER") # 발신할 이메일

EMAIL_HOST_PASSWORD = os.environ.get("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 = "[Watti]"

저번 포스팅에서 쓴 장고에서 이메일을 보내기 위한 설정값들에 이어서, 회원가입을 할때 이메일 인증 과정을 거치도록 나머지 설정들을 쓴다.

- views.py

# views.py
from django.http import HttpResponseRedirect
from rest_framework.views import APIView
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('/') # 인증성공

    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('/') # 인증실패
        return email_confirmation

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

유저가 인증 이메일을 받고, 해당 계정을 인증하기 위해 확인하는 부분이다.

- urls.py

# urls.py

from dj_rest_auth.registration.views import VerifyEmailView

# api/user/
urlpatterns = [
    # 일반 회원 회원가입/로그인
    path('dj-rest-auth/', include('dj_rest_auth.urls')),
    path('dj-rest-auth/registration/', include('dj_rest_auth.registration.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'),
]

여기까지 하면 이제 이렇게 몬생긴 인증 이메일이 온다.


이메일 템플릿 설정하기

- settings.py

템플릿 경로 지정을 해주고

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'), # 여기 추가!
        ],
        ...
    },
]

- 템플릿 만들기

manage.py랑 같은 곳에 templates/account/email 폴더를 차례대로 만들어준다.

이 안에서 이메일 제목과 본문에 보여질 템플릿을 각자 만들 수 있는데, 파일명은 완전 동일해야 한다.

제목 : email_confirmation_subject.txt
본문 : email_confirmation_signup_message.html

# email_confirmation_subject.txt (제목)
Watti 회원가입 인증 이메일입니다.
<!-- email_confirmation_signup_message.html (본문) -->
{% load account %}
{% load i18n %}
{% block content %}
{% autoescape off %}
{% user_display user as user_display %}
{% blocktrans with site_name=current_site.name site_domain=current_site.domain %}

<!DOCTYPE html>
<html>
...
<p>
  귀하의 아이디는
  	<span style="font-weight:bold;">{{ user_display }}</span>
  입니다.
</p>
  
<a href="{{ activate_url }}" target="_blank">
  계정 인증하기
</a>
...
</html>

{% endblocktrans %}
{% endautoescape %}
{% endblock %}

테스트

이제 회원가입을 하면

인증 이메일이 보내졌다는 응답이 오고,

admin에서는 유저 등록은 됐지만 verifiedfalse인 것을 볼 수 있다.

이메일을 확인해보면 템플릿도 잘 적용됐당. 저 계정 인증하기 버튼을 누르면 127.0.0.1:8000으로 리다이렉트되고,

verifiedtrue가 된다.

로그인을 하면 access token이 나옴.


Reference

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

profile
일기장같은 공부기록📝
post-custom-banner

3개의 댓글

comment-user-thumbnail
2022년 11월 4일

안녕하세요! 혹시 이 포스팅관련 코드 깃허브를 볼 수 있을까요??

1개의 답글