비밀번호 이메일 보내기 기능

·2024년 12월 11일

개인프로젝트

목록 보기
11/11

메일을 보내려면 메일 서버를 활용해야 한다.

SMTP (Simple Mail Transfer Protocol)

  • 이메일을 보낼 때 사용하는 프로토콜.

작동 방식

  1. 사용자가 이메일을 작성하고 보내면 SMTP 서버가 이를 수신한다.
  2. 이메일을 수신자의 메일 서버로 전달

특징

주로 발신 서버 역할을 하고, 포트 번호는 보통 25번, 보안 연결에서는 587번이나 465번을 사용한다.

POP3(Post Office Protocol 3)

  • 이메일을 받을 때 사용하는 프로토콜입니다.

작동 방식

  • 이메일 클라이언트가 POP3 서버에 접속하여 이메일을 다운로드한다.
  • 기본적으로 이메일을 다운로드 후 서버에서 삭제한다.

특징

이메일을 로컬 컴퓨터로 가져와 오프라인으로도 읽을 수 있다. 서버에 이메일이 남지 않아 저장 공간 부담이 줄어들고, 포트 번호는 기본적으로 110번, 보안 연결에서는 995번을 사용.

IMAP (Internet Message Access Protocol)

IMAP은 이메일을 받을 때 사용하는 프로토콜 중 하나로, POP3와는 다른 특징을 가지고 있다.
서버에 이메일을 저장한 상태로 관리하면서 다양한 기기에서 이메일을 동기화한다.
클라이언트에서 이메일을 확인하거나 관리해도 이메일은 서버에 남아 있어 어디서든 동일한 상태로 접근 가능.
여러 기기에서 이메일을 동시에 확인할 때 매우 유용하고, 이메일이 서버에 저장되어서 데이터 손실 위험이 적다.

IMAP의 특징

  • 서버 중심: 이메일이 항상 서버에 저장되므로 여러 기기에서 동일한 이메일 상태를 확인할 수 있다.
  • 동기화 가능: 이메일 읽음/삭제/이동 등의 작업이 모든 기기에 동기화.
  • 폴더 지원: 클라이언트에서 폴더를 생성하고 이메일을 분류할 수 있으며 이 상태도 서버에 반영된다.
  • 오프라인 모드: 일부 클라이언트는 이메일을 로컬에 캐시로 저장해 오프라인에서도 읽을 수 있게 지원.

Google Gmail 사용

		<!-- 메일 api -->	
		<dependency>
	        <groupId>org.apache.commons</groupId>
	        <artifactId>commons-email</artifactId>
	        <version>1.2</version>
 		</dependency>
 		<dependency>
	        <groupId>javax.mail</groupId>
	        <artifactId>mail</artifactId>
	        <version>1.4.7</version>
 		</dependency>
 		<dependency>
	        <groupId>org.springframework</groupId>
	        <artifactId>spring-context-support</artifactId>
	        <version>${org.springframework-version}</version>
 		</dependency>
		<!-- 메일 api 끝 -->			

pom.xml로 가서 메일을 사용할 수 있는 dependency를 추가해준다.

	<!-- 메일 -->
	<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="dltmf1045@gmail.com"/>
	<property name="password" value="2차 앱 비밀번호"/>
	<property name="javaMailProperties">
	<props>
	<prop key="mail.smtp.auth">true</prop>
	<prop key="mail.smtp.starttls.enable">true</prop>
	<prop key ="mail.smtp.ssl.protocols">TLSv1.2</prop>
	</props>
	</property>
	</bean>

라이브러리를 다운 받았으면 root-context로 가서 bean등록 해주기
value에는 우리는 호스트 메일주소에 구글 메일을 사용할 것이다.

package com.myaws1125.myapp.util;

import java.io.IOException;

import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;

import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

public class MailHandler {
	private JavaMailSender sender;
	private MimeMessage message;
	private MimeMessageHelper messageHelper;
	//create
	public MailHandler(JavaMailSender jSender) throws MessagingException {
		this.sender = jSender;
		message = jSender.createMimeMessage();
		messageHelper = new MimeMessageHelper(message,true,"UTF-8");
	}

	public void setFrom(String fromAddress) throws MessagingException {
		messageHelper.setFrom(fromAddress);
	}
	
	public void setTo(String email) throws MessagingException {
		messageHelper.setTo(email);
	}
	//title
	public void setSubject(String subject) throws MessagingException {
		messageHelper.setSubject(subject);
	}
	//contents
	public void setText(String text, boolean useHtml) throws MessagingException{
		messageHelper.setText(text,useHtml);
	}
	//file
	public void setAttach(String displayFileName, String pathToAttachment) throws MessagingException, IOException{
		HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder
			      .getRequestAttributes()).getRequest();
		String filePath = request.getSession().getServletContext().getRealPath("/resources/static/img/");
		DataSource dataSource = new FileDataSource(filePath+pathToAttachment);
		messageHelper.addAttachment(displayFileName, dataSource);
	}
	//image
		public void setInline(String contentId, String pathToInline) throws MessagingException, IOException{
			HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder
				      .getRequestAttributes()).getRequest();
			String filePath = request.getSession().getServletContext().getRealPath("/resources/static/img/");
			DataSource dataSource = new FileDataSource(filePath+pathToInline);
			messageHelper.addInline(contentId,dataSource);
		}
	//send
	public void send() {
		try {
			sender.send(message);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

util 폴더에 MailHandler 넣기. 얘를 통해서 사용할 것이다.

@Service
public class MailApi {
	
	@Autowired(required=false)
	private JavaMailSender mailSender;
	
	public void sendEmail(HttpServletRequest request,
			HttpServletResponse response,
			HashMap<String,Object> hm) {

		String subject = hm.get("subject").toString();
		String contents = hm.get("subject").toString();
		String receiverEmail = hm.get("receiveremail").toString();
		String senderEmail = hm.get("senderemail").toString();

		
		try {
			MailHandler mailHandler = new MailHandler(mailSender);
			mailHandler.setTo(receiverEmail); // 받는사람
			mailHandler.setFrom(senderEmail); // 보내는사람
			mailHandler.setSubject(subject); //메일제목
			mailHandler.setText(contents, true); // 메일 내용
			mailHandler.send(); // 모든게 채워지면 보낸다.
			
		} catch (MessagingException e) {
			
			e.printStackTrace();
		}
	}

api패키지를 생성해서 안에 MailApi 클래스 생성

@Controller
@RequestMapping(value="/email/")
public class ApiController {
	
	
	@Autowired(required=false)
	private MailApi mailApi;
	
	@RequestMapping(value="emailWrite.aws", method=RequestMethod.GET)
	public String emailWrite() {
		
		String path = "WEB-INF/email/emailWrite";
		return path;
	}

컨트롤러에서도 ApiController 클래스를 하나 생성해준다.

jsp파일 하나 새로 만들어주기. boardWrite.jsp 파일을 그대로 복사해서 조금 손 볼 것이다.

<script>
function check() {
	
	//유효성 검사하기
	var fm = document.frm;
	
	if(fm.subject.value == "") {
		alert("제목을 입력해주세요");
		fm.subject.focus();  // 커서가 입력안한 해당 자리로 갈수 있도록 
		return;
	} else if(fm.contents.value =="") {
		alert("내용을 입력해주세요");
		fm.contents.focus(); 
		return;
	}else if(fm.senderemail.value =="") {
		alert("보내는 메일주소를 입력해주세요");
		fm.senderemail.focus(); 
		return;
	}else if(fm.receiveremail.value =="") {
		alert("받는 사람 메일주소를 입력해주세요");
		fm.receiveremail.focus(); 
		return;
	}
	
	var ans = confirm("발송하시겠습니까?");  // 함수의 값은 참과 거짓 true false로 나눈다. 
	
	if(ans == true) {	
		fm.action="${pageContext.request.contextPath}/email/emialWriteAction.aws"; 
		fm.method="post";
		fm.submit();	//파일 업로드를 포함한 폼 데이터를 전송할 때 필요한 인코딩 방식을 지정
	}
		return; 
}
</script>

스크립트 부분

<form name="frm">
    <div class="container">
        <!-- 제목 입력 박스 -->
        <div class="form-group">
            <label for="title">&#128394;&#65039; 메일 제목:</label>
            <input type="text" id="subject" name="subject" class="input-box" placeholder="제목을 입력하세요">
        </div>

        <!-- 글 내용 입력 박스 -->
        <div class="form-group">
            <label for="content">&#128221;메일 내용:</label>
            <textarea id="contents" name="contents" class="input-box" rows="10" placeholder="내용을 입력하세요"></textarea>
        </div>

		
        <!-- 작성자, 비밀번호 -->
        <div class="form-group file-writer-password">
            <div>
                <label for="writer">보내는 메일</label>
                <input type="text" id="senderemail" name="senderemail">
            </div>
            <div>
                <label for="pass">받는 메일</label>
                <input type="text" id="receiveremail" name="receiveremail">
            </div>
        </div>
        
        <!-- 저장하기 버튼 -->
        <div class="form-group2">
            <button type="button" class="btn" onclick="check();">저장</button>
            <button type="button" class="btn" onclick="history.back();">취소</button>
		</div>
        </div>
    </div>
</form>

html form 부분

	@RequestMapping(value="emailWriteAction.aws", method=RequestMethod.POST)
	public String emailWriteAction(
			@RequestParam("subject") String subject,
			@RequestParam("contents") String contents,
			@RequestParam("senderemail") String senderemail,
			@RequestParam("receiveremail") String receiveremail,
			HttpServletRequest request,
			HttpServletResponse response
			) {
		
		HashMap<String,Object> hm = new HashMap<String,Object>();
		hm.put("subject", subject);
		hm.put("contents", contents);
		hm.put("senderemail", senderemail);
		hm.put("receiveremail",receiveremail);
		
		mailApi.sendEmail(request, response, hm);
		
		String path = "redirect:/"; // 메인으로 가게끔
		return path;
	}

컨트롤러로 돌아와서 동작처리 메서드 구현해주기

MailApi로 와서 값 넣어주면 된다.

메일 발송을 하기 위해서는 발송 주체가 되는 계정으로 로그인한 후 'Google 계정-> 보안 탭에서 2차 인증을 완료하고,
②추가로 '앱 비밀번호' 생성한 다음 ③해당 '앱 비밀번호'를 기존 패스워드 대신 저장해 사용하면 된다.

0개의 댓글