반응형
12-24 20:16
Today
Total
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
관리 메뉴

개발하는 고라니

[Spring] 메일 송신 본문

Framework/Spring

[Spring] 메일 송신

조용한고라니 2020. 12. 2. 01:32
반응형

Spring 프레임워크를 공부하던 도중, 문득 회원가입 시 E-mail 인증이 필요할 경우 서버에서 E-mail을 보내게 되는데,

이는 어떻게 작동하는건지 궁금해서 찾아보고 실습해보았다.

 

 이메일 보내는 것을 하기 전, 간단히 메일 전송의 원리와 전자우편, 프로토콜에 대해 알아보았다.

메일 전송의 원리

  1.  사용자는 Mail Client와 같은 프로그램을 통해 메일을 작성 후, SMTP(Simple Mail Transfer Protocol)를 이용해 메일 데몬으로 메세지를 전송한다.
  2. 메일 데몬은 종단 간 Client의 주소를 분석하고 가장 가까운 (송신자 소속)Mail Server로 메세지와 정보를 넘긴다. (메일 데몬은 일종의 process로, 송신자의 메일과 정보를 메일 서버가 해석 가능하도록 가공한다.)
  3. 송신자가 보낸 메세지가 송신자 측의 전자우편을 관리하는 Mail Server에 전달되고, Mail Server는 수신자의 전자우편 주소를 분석해 최단경로를 찾아 근접한 Mail Server에 메세지를 전달한다.
  4. 최종 수신자 측의 Mail Server에 도착하기까지 연속적으로 전달하는 중계작업이 계속된다. 서로 근접한 Mail Server들 간에 전자우편을 계속해서 중계해 나가는 방법을 통해 메일을 "저장 후 전송"하는 서비스를 제공한다.
  5. 위와 같은 일련의 반복작업이 이뤄지면, 송수신자는 비로소 메일을 교환할 수 있게 된다.

 

전자우편의 주소체계와 구성

  • E-mail은 @을 구분자로 좌측에 소속된 서버에서 부여받은 ID와 우측에 소속 서버 주소의 주소를 사용
  • 전자우편은 [주소, 날짜, 주제(제목)]을 포함하는 메일 헤더와 메일의 [내용]이 포함된 메일 본체로 구성됨

 

Protocol

  • SMTP(Simple Mail Transfer Protocol) : 일반적으로 메일을 송신할 때 사용된다. 이와 관련된 프로토콜에 대한 표준은 STD와 RFC에서 정하였다. 서버 to 서버로의 프로토콜이며, 이외의 다른 여러 프로토콜은 메세지를 접속하기위해 사용된다.
  • POP(Post Office Protocol) : 인터넷 메일 Client가 메일 서버로부터 메일을 꺼내기 위한 규약이다. 인터넷에서 사실상 표준이 되어있다. 메일의 수신을 위한 프로토콜이며, 전자우편의 헤더와 본문 모두를 사용자의 컴퓨터로 다운로드한다. 이 프로토콜은 TCP 세션의 '109'번 포트를 쓰는데 최근 많이 사용되는 POP3는 110번 포트를 사용한다.

<-- ------------------------------------------------------------------------------------------------------------------------- -->

Spring으로 메일 보내기

 

* 메일을 보내려면 발송해주는 메일 서버(Mail Server)가 필요한데, 메일 서버를 통해 보낼 때 메일 서버에 접속하는 방법은 주로 2가지가 있다.

 

  1. 메일 서버에 계정이 있어서 ID/Password로 인증 후 메일을 보내는 경우(가장 일반적인 경우)
  2. 서버가 릴레이를 허용하는 경우(해당 메일 서버에 계정이 없어도 메일을 발송할 수 있다.)

본 포스트에서는 1번의 경우를 사용해 간단하게 메일의 제목과 본문을 보내는 작업을 수행해보겠다.

 

  • 의존성 주입 (pom.xml)
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.0.7.RELEASE</version>
</dependency>
<!--javax.mail.Internet.MimeMessage를 사용하기 위한 Dependency -->
<dependency>
    <groupId>com.sun.mail</groupId>
    <artifactId>javax.mail</artifactId>
    <version>1.6.2</version>
</dependency>

* Spring의 기본 메일 인터페이스는 MailSender인데, 이는 Spring의 SimpleMailMessage를 이용하며 첨부파일 등을 지원하지 않아 MIME Message를 이용하기로 한다.

 

  • Bean 등록

mailSender를 빈으로 등록하기위해 root-context.xml에 등록하였으나 mail-context.xml을 따로 작성하여 등록해도 된다. 다음은 gmail서버를 이용해 메일을 보내기 위한 빈 등록이다.

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="smtp.gmail.com" />
    <property name="port" value="587" />
    <property name="username" value="Account@gmail.com" />
    <property name="password" value="Password" />
    <property name="javaMailProperties">
    <props>
    <prop key="mail.smtp.auth">true</prop>
    <prop key="mail.smtp.starttls.enable">true</prop>
    </props>
    </property> 
</bean>

** 구글은 인증에 TLS를 사용하는데, TLS란 SSL과 같은 것이지만 SSL 3.0부터 TLS라 부른다.

 

  • MailVO
@Data
public class MailVO {

	private String subject;
	private String text;
	private String from;
	private String to;
}

 

  • MailController
@Controller
@Log4j
@RequestMapping("/mail")
public class MailController {

	@Autowired
	private JavaMailSenderImpl mailSender;
	
	
	@GetMapping("/send")
	public void send() {
		log.info("===============================");
		log.info("@Mail Controller, <GET> send");
	}
	
	@PostMapping("/send")
	public ModelAndView send(MailVO vo, ModelAndView mv) {

		mv.setViewName("/home");
		log.info("@MailController, sendPost MailVO : " + vo);
		final MimeMessagePreparator preparator = new MimeMessagePreparator() {
			
			@Override 
			public void prepare(MimeMessage mimeMessage) throws Exception {
				
				final MimeMessageHelper helper = 
						new MimeMessageHelper(mimeMessage, true, "UTF-8"); 
					helper.setFrom(vo.getFrom()); 
					helper.setTo(vo.getTo()); 
					helper.setSubject(vo.getSubject()); 
					helper.setText(vo.getText(), true); 
				} 
			}; 
		mailSender.send(preparator);
			
		return mv;
	}

}

 

  • send.jsp
<div class="form-email">
	<form action="/mail/send" method="post">
		<div class="standard-rectangle">
			<label>수신자</label>
			<input type="text" name="to">
		</div>
		<div class="standard-rectangle">
			<label>메일 제목</label>
			<input type="text" name="subject">
		</div>
		<div class="standard-rectangle">
			<label>본문</label>
			<textarea rows="8" cols="60" name="text"></textarea>
		</div>
		<div class="standard-rectangle">
			<label>발신자</label>
			<input type="text" name="from">
		</div>
		<div>
			<input type="submit" class="submit" value="Submit">
		</div>
	</form>
</div>

간단하게 1. 메일을 받을 주소(To), 2.메일 제목(Subject), 3.본문(Text), 4.메일을 보내는 주소(From)을 입력해

POST 요청한다. 하지만 4.메일을 보내는 주소는 어떤 것을 입력하여도 Bean을 등록할 때 설정한 "Account@gmail.com"주소에서 보내진다.

 

중요한 것은 안티바이러스, 백신 프로그램은 종료 후에 시도해야 정상적으로 작동한다. 이를 켜두고 실행하면 500 Error가 발생한다.

반응형
Comments