이메일 인증 기능 추가
파이보 추가 기능 항목에는 없지만 필요한 기능인 것 같아 추가했습니다.
SMTP 설정
먼저 이메일을 보내기 위해 SMTP 설정을 해줍니다. 저는 네이버를 사용했습니다.
(SMTP란? Simple Mail Transfer Protocol의 약자로 이메일을 송신하는 데 사용되는 인터넷 표준 프로토콜입니다)
네이버 메일에 접속한 후 환경설정 - IMAP/SMTP 설정에서 사용함을 체크하고 저장하면 됩니다.
config/settings/base.py에서 SMTP를 사용할 수 있도록 설정해줍니다.
EMAIL_HOST_USER에 계정 정보에 적힌 아이디를, PASSWORD에는 네이버 비밀번호를 적으면 됩니다.
보안에 유의하세요!
# SMTP 설정
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.naver.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = '아이디'
EMAIL_HOST_PASSWORD = '비밀번호'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
인증 모델 생성
개인 정보를 채우고 회원가입 버튼을 눌렀을 때 인증번호를 생성해서 이메일로 발송하고 입력받은 인증번호가 일치하는지 확인해야 합니다. 이를 위해서 common/models.py에 다음과 같이 모델을 생성해줍니다.
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import uuid
class EmailVerification(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
verification_code = models.UUIDField(default=uuid.uuid4, editable=False)
created_at = models.DateTimeField(auto_now_add=True)
def is_valid(self):
return timezone.now() < self.created_at + timezone.timedelta(minutes=10)
uuid를 통해 인증번호를 생성하고 이를 유저에게 값을 할당해줍니다.
is_valid는 10분 이내에 인증이 됐는지를 확인하는 함수입니다.
python manage.py makemigrations와 python manage.py migrate로 DB에 적용해줍니다.
만약 오타 등으로 수정한 뒤 다시 적용 시키려면 common/migrations 폴더에 해당되는 파일을 제거하고 다시 migrate해주면 됩니다.(예: 0001_EmailVerification.py)
코드 작성
이제 인증 기능을 구현해봅시다. 우선, signup 함수를 다음과 같이 수정합니다.
common/views.py
from .models import EmailVerification
def signup(request):
if request.method == "POST":
form = UserForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False # 이메일 인증 전까지 비활성화
user.save()
# 이메일 인증 객체 생성 및 저장
verification = EmailVerification.objects.create(user=user)
verification_code = verification.verification_code
# 이메일 발송
send_verification_email(user, verification_code)
return redirect('common:verify_email') # 인증 코드 입력 페이지로 이동
else:
form = UserForm()
return render(request, 'common/signup.html', {'form': form})
인증 객체를 생성하고 인증 코드를 이메일 발송 함수에 넘겨줍니다. 이후 인증 코드를 입력하는 창으로 넘어갑니다.
이메일 발송 함수는 다음과 같습니다.
from django.core.mail import EmailMessage
def send_verification_email(user, verification_code):
subject = '이메일 인증'
message = f'인증 코드는 {verification_code} 입니다'
from_email = '네이버아이디@naver.com'
to_email = [user.email]
email = EmailMessage(subject, message, from_email, to_email)
email.send(fail_silently=False)
제목, 내용, 발신자, 수신자로 내용을 채워줍니다.
다음은 인증 코드를 입력받고 확인하는 코드입니다.
def verify_email(request):
if request.method == "POST":
# 사용자로부터 POST로 인증 코드 받기
code = request.POST.get('verification_code')
code = code.strip() # 공백 제거
try:
verification = EmailVerification.objects.get(verification_code=code)
if verification.is_valid():
user = verification.user
user.is_active = True # 계정 활성화
user.save()
verification.delete()
login(request, user)
return redirect('index')
else:
return render(request, 'common/verify_email.html', {'error': '인증 코드가 만료되었습니다.'})
except EmailVerification.DoesNotExist:
return render(request, 'common/verify_email.html', {'error': '잘못된 인증 코드입니다.'})
# GET 요청 시 인증 코드 입력 폼 페이지를 렌더링
return render(request, 'common/verify_email.html')
확인이 완료되면 user.is_active가 True로 바뀌며 계정이 활성화 됩니다. 활성화된 아이디의 인증 객체는 삭제합니다.
common/urls.py에 path도 추가해줍니다.
path('verify_email/', views.verify_email, name='verify_email'),
마지막으로 인증코드를 입력하는 화면입니다.
templates/common/verify_email.html
{% extends "base.html" %}
{% block content %}
<div class="container my-3">
<h3>이메일 인증</h3>
{% if error %}
<div class="alert alert-danger">{{ error }}</div>
{% endif %}
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label for="verification_code">인증 코드</label>
<input type="text" class="form-control" name="verification_code" id="verification_code" required>
</div>
<button type="submit" class="btn btn-primary">인증하기</button>
</form>
</div>
{% endblock %}
이렇게 이메일 인증 기능이 구현되었습니다.
기능 구현 결과 화면입니다.
'개발 > django' 카테고리의 다른 글
점프 투 장고 추가 기능(카테고리) (1) | 2024.11.10 |
---|---|
점프 투 장고 추가 기능(댓글) (0) | 2024.11.07 |
점프 투 장고 추가 기능(답변 페이징과 정렬) (0) | 2024.11.05 |