이번에 인턴하는 회사 홈페이지를 리뉴얼하는데 관리자 서버를 하나 띄우기로 했다. 서버를 구현하는데 문의하기라는 API를 만들 때 직접 회사 이메일로 문의내용이 전송되게 했으면 좋을것 같다고 하셔서 SMTP에 대해 검색해보기 시작했다. 그러다 django에서 smtp사용해서 쉽게 메일을 보낼 수 있다고 해서 한번 적용해보기로 했다.
간이 전자 우편 전송 프로토콜(Simple Mail Transfer Protocol, SMTP)은 인터넷에서 이메일을 보내기 위해 이용되는 프로토콜으로 사용하는 TCP 포트번호는 25번이다. 상대 서버를 지시하기 위해서 DNS의 MX레코드가 사용된다. RFC2821에 따라 규정되어 있다. 메일 서버간의 송수신뿐만 아니라, 메일 클라이언트에서 메일 서버로 메일을 보낼 때에도 사용되는 경우가 많다.
SMTP는 텍스트 기반의 프로토콜로서 요구/응답 메시지뿐 아니라 모든 문자가 7bit ASCII로 되어있어야 한다고 규정되어 있다. 이 때문에 문자 표현에 8비트 이상의 코드를 사용하는 언어나 첨부파일과 자주 사용되는 각종 바이너리는 마임(MIME)이라고 불리는 방식으로 7비트로 변환되어 전달된다.
SMTP는 메시지를 생성하는 방법을 규정하지 않는다. 메시지 생성을 위하여 로컬 편집이나 단순한 전자 우편 응용이 사용된다. 메시지가 생성되면 호출된 SMTP가 메시지를 받고 TCP를 이용하여 다른 호스트의 SMTP에게 전달한다.
Django에서는 내장된 SMTP를 통해서 메일을 쉽게 보낼 수 있다. Gmail의 SMTP 서버를 이용해 메일을 전송하는 상황이라면 몇 가지 설정이 필요하다.
우선 보안 수준이 낮은 앱 및 Google 계정 설정을 해주어야 한다.
보안수준이 낮은 앱 설정으로 들어가서 허용을 눌러준다.
이 후에는 Django의 Settings.py 파일 아래에 코드 몇줄을 추가해주면 설정이 완료된다.
settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'user@gmail.com(위 설정에 사용한 GMail 계정)'
EMAIL_HOST_PASSWORD = '위 설정에 사용한 GMail 비밀번호'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
이제 메일을 보낼 코드만 짜주면 된다.
DRF로 API서버를 만들었기 때문에 문의하기 모델과 시리얼라이저를 만들어준다.
# models.py
class Contact(BaseModel):
LOCATION_CHOICE = [
('seoul', 'seoul'),
('incheon', 'incheon')
]
location = models.CharField(max_length=10, choices=LOCATION_CHOICE)
name = models.CharField(max_length=50)
phone = PhoneNumberField()
email = models.EmailField()
comment = models.TextField()
class Meta:
db_table = 'contact'
# serializer.py
class ContactSerializer(serializers.ModelSerializer):
class Meta:
model = Contact
fields = '__all__'
이제 view를 사용해서 데이터를 저장하고 메일을 보내면 된다.
# views.py
class ContactView(APIView):
permission_classes = [AllowAny]
def post(self, request):
serializer = ContactSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
# smtp사용해서 메일보내는 코드
subject = "["+serializer.data['name']+"]의 문의" # 메일 제목
to = ["@gmail.com"] # 문의 내용을 보낼 메일 주소, 리스트 형식
message = serializer.data['comment'] # 메일 내용
EmailMessage(subject=subject, body=message, to=to).send() # 메일 보내기
return Response(serializer.data, status=201)
return Response(serializer.errors, status=400)
포스트맨에서 테스트하면 아래처럼 인스턴스가 만들어진다.
이후에 메일을 확인해보면 메일이 정상적으로 오는 것을 확인할 수 있다.