[4th TeamProject] - 이메일 인증

장현웅·2023년 10월 24일
1

회원가입 시 이메일 인증 기능을 구현해봤습니다.

  1. 이메일 인증을 구현하기 위해 필요한 라이브러리를 설치합니다.
pip install django djangorestframework django-rest-auth
  1. 인증 이메일을 발송하는 로직을 View에 정의합니다.

[ 인증 이메일 발송 View ]

class SendVerificationEmailView(APIView):
    def post(self, request):
            
        user = User.objects.get(email=request.data['email'])

        token = default_token_generator.make_token(user)
        uid = urlsafe_base64_encode(force_bytes(user.pk))

        verification_url = f"http://127.0.0.1:8000/verify-email/{uid}/{token}/"
        
        subject = '이메일 확인 링크'
        message = f'이메일 확인을 완료하려면 다음 링크를 클릭하세요: {verification_url}'
        from_email = 'hyeonwoongjang01@gmail.com'
        recipient_list = [user.email]

        send_mail(subject, message, from_email, recipient_list)

        return Response(status = status.HTTP_200_OK)
  • token = default_token_generator.make_token(user) : default_token_generator는 Django에서 제공하는 토큰 생성기입니다. 이 부분에서는 user 객체를 사용하여 이메일 확인을 위한 토큰을 생성합니다.
  • uid = urlsafe_base64_encode(force_bytes(user.pk)) : urlsafe_base64_encode 함수를 사용하여 사용자의 기본 키(pk)를 URL에서 사용 가능한 안전한 형식(Base64 문자열에서 -와 _를 +와 /로 대체)으로 인코딩합니다. 이 인코딩된 값은 이메일 확인 링크 URL에 포함됩니다.
  • verification_url = f"http://127.0.0.1:8000/verify-email/{uid}/{token}/" : uid와 token 값을 사용하여 이메일 확인을 위한 URL을 생성합니다. 서버에는 이 URL 엔드포인트에 연결된 View에 이메일 인증에 대한 로직을 정의합니다.
  • send_mail(...): Django의 send_mail 함수를 사용하여 이메일을 전송합니다.
    • subject : 이메일의 제목입니다.
    • message : 이메일의 내용입니다. 이 내용에 이메일 확인을 완료하기 위한 링크를 포함시킵니다.
    • from_email : 이메일을 보내는 주소입니다.
    • recipient_list : 이메일을 받을 사용자의 이메일 주소 목록입니다.
  1. 인증 이메일을 발송할 url 엔드포인트를 정의합니다.

[ 인증 이메일 발송 url ]

from django.urls import path
from user import views

urlpatterns = [
    path('send-verification-email/', views.SendVerificationEmailView.as_view(), name='send_verification_email_view'),
]
  1. 이메일 전송을 위한 SMTP 서버에 대한 설정을 settings.py에 정의합니다.
EMAIL_HOST = 'smtp.gmail.com' 					# 메일 호스트 서버
EMAIL_PORT = 587 			 					# SMTP 포트 번호
EMAIL_HOST_USER = 'hyeonwoongjang01@gmail.com' 	# 서비스에서 사용할 Gmail
EMAIL_HOST_PASSWORD = ''         				# 서비스에서 사용할 Gmail의 앱 password

# TLS 보안 설정 - SMTP 서버와 통신할 때 TLS(보안) 연결을 사용할지 여부. 보통 587 포트에서 명시적 TLS 연결에 사용됨. 기본값은 False.
EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
  • EMAIL_HOST : 이메일을 보낼 SMTP 서버의 호스트 주소입니다. Gmail의 SMTP 서버 주소는 'smtp.gmail.com'입니다.
  • EMAIL_PORT : SMTP 서버와 통신할 때 사용하는 포트 번호입니다. Gmail의 SMTP 서버는 TLS(보안)을 사용하는 587 포트를 주로 사용합니다.
  • EMAIL_HOST_USER : 이메일을 보낼 서비스에서 사용할 Gmail 계정의 이메일 주소입니다. 이 계정은 이메일을 보내는 데 사용됩니다.
  • EMAIL_HOST_PASSWORD : EMAIL_HOST_USER에 대한 비밀번호입니다. 이 비밀번호는 이메일 서버에 연결하여 이메일을 보낼 때 사용됩니다. 이 부분은 보안 상 주의해야 하며, 보안에 취약한 공개 코드와 함께 사용하지 말아야 합니다.
  • EMAIL_USE_TLS : 이 설정은 SMTP 서버와의 통신 시 TLS(보안) 연결을 사용할지 여부를 지정합니다. True로 설정하면 TLS를 사용하며, 대개 587 포트에서 명시적 TLS 연결을 사용합니다.
    • TLS (Transport Layer Security) : 네트워크 통신을 암호화하여 데이터의 기밀성과 무결성을 보호하기 위한 암호화 프로토콜입니다. TLS는 데이터를 전송하는 과정에서 중간자 공격과 같은 보안 위협을 방지하기 위해 사용됩니다.
  • DEFAULT_FROM_EMAIL : 이메일의 발신자 주소를 설정하는데 사용됩니다. 보통 EMAIL_HOST_USER와 같은 값을 사용합니다. 이 주소는 이메일 수신자가 보게되는 발신자 주소로 표시됩니다.
  1. 인증 이메일에 포함된 인증을 완료하기 위한 URL 엔드포인트를 urls.py에 추가합니다.
from django.urls import path
from user import views

urlpatterns = [
    path('send-verification-email/', views.SendVerificationEmailView.as_view(), name='send_verification_email_view'),
    path('verify-email/<str:uidb64>/<str:token>/', views.VerifyEmailView.as_view(), name='verify_email_view'),
]
  1. 이메일 인증을 완료하는 로직을 View에 정의합니다.
class VerifyEmailView(APIView):
    def get(self, request, uidb64, token):
        # uidb64와 token을 사용하여 사용자 확인
        uid = urlsafe_base64_decode(uidb64)
        user = User.objects.get(id=uid)

        if default_token_generator.check_token(user, token):
            user.is_active = True
            user.save()
        return Response(status=status.HTTP_200_OK)
  • uid = urlsafe_base64_decode(uidb64) : uidb64 값은 URL에서 안전하게 전송되어야 하므로, 이 값을 다시 원래의 사용자 기본 키(primary key)로 디코딩합니다. 이건 사용자를 식별하는 데 사용됩니다.
  • default_token_generator.check_token(user, token) : default_token_generator를 사용하여 이메일 확인을 위한 토큰을 검사합니다. 이 토큰은 이메일 확인을 수행하기 위해 이메일 확인 링크를 클릭한 사용자와 관련된 데이터를 인증하는 데 사용됩니다.
  • user.is_active = True : 사용자 객체의 is_active 속성을 True로 설정하여 사용자를 활성화 상태로 변경합니다. 일반적으로 이것은 사용자의 이메일이 성공적으로 확인되었음을 나타냅니다.

다음 포스팅에는 Celary 라이브러리를 사용해서 이메일 인증을 비동기 방식으로 회원가입과 동시에 진행될 수 있도록 구현해보겠습니다.

1개의 댓글

comment-user-thumbnail
2023년 10월 25일

이메일 인증 구현 과정이 자세히 설명 되어있어 후에 다시 글을 볼 때도 이해하기가 쉽겠네요~

답글 달기