[비밀번호 찾기] Naver SMTP 서버로 메일 보내기
프로젝트를 진행하면서 비밀번호 찾기 할 때 메일로 임시비밀번호를 보내고싶었는데, 찾아보니 생각보다 어렵지 않았다. 그런데 차근차근 따라하지 않으면 에러파티를 면할 수 없었기에.. 차근차근 따라할 수 있도록 정리를 해보려고 한다.
시작하기 전에
SMTP(Simple Mail Transfer Protocol, 간이 전자 우편 전송 프로토콜)
- 인터넷에서 이메일을 보내기 위한 프로토콜
- 메일 서버 간 송수신 또는 클라이언트에서 메일 서버로 보낼 때 사용된다.
TLS(Transport Layer Security, 전송 계층 보안)
클라이언트 및 서버가 네트워크 통신을 하는 과정에서 도청 등의 행위를 방지하기 위해 암호화를 해 통신 기밀성을 유지시켜주는 암호 규약
TLS의 3단계 기본 절차
- 서버와 클라이언트는 지원 가능한 알고리즘(키 교환, 인증, 대칭키 암호, 해시 함수)을 서로 교환
- 키 교환, 인증
- 대칭키 암호로 암호화하고 메시지 인증
SSL(Secure Sockets Layer, 보안 소켓 레이어)
- 서버와 클라이언트 간 암호화된 통신을 구현하는 글로벌 표준 보안 기술
- TLS는 SSL에 기반해 만들어진 기술이다.
참고: 위키백과
Naver에서 Host 정보 가져오기
Naver 계정에 로그인 후 메일 페이지에 들어가서 왼쪽 하단에 환경설정을 눌러준다.
환경 설정의 메뉴 중 POP3/IMAP 설정을 눌러준다.
IMAP/SMTP 설정 탭에서 IMAP/SMTP 사용을 '사용함'으로 지정하고 확인 버튼을 눌러준다.
위 사진의 모습에서 아래 사진의 모습으로 바뀌도록 해주면 된다.
그러고 아래를 보면 메일 계정 설정이 있을 것이다. 여기서 SMTP 서버명과 SMTP 포트, 아이디, 비밀번호를 알아두자. 서버와 포트번호는 모두 동일하고, 아이디는 네이버 아이디이며 비밀번호도 네이버 비밀번호이다.
Dependency (Maven) 설정
자바로 메일을 보내기 위해서 아파치에서 제공하는 commons email 라이브러리를 사용하도록 하자. 우리는 여기서 주어지는 클래스 중 HtmlEmail을 사용할 것이다. 다른 클래스가 무엇무엇이 있는지와 기타 설명들이 필요하면 여기를 확인하도록 하자.
x
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
pom.xml 파일에 dependency를 추가해준 뒤 메이븐을 빌드 해주자.
메일 보낼 클래스
컨트롤러에서 받는 사람의 이메일, 메일 제목, 메일 내용만 전달 받아서 전송할 수 있도록 매개변수로 지정해두고 작성했다.
xxxxxxxxxx
import org.apache.commons.mail.HtmlEmail;
public class MailUtil {
public static void sendMail(String email, String subject, String msg) throws Exception {
// Mail Server 설정
String charSet = "utf-8";
String hostSMTP = "smtp.naver.com"; // SMTP 서버명
String hostSMTPid = "네이버 아이디"; // 아이디
String hostSMTPpwd = "네이버 비밀번호"; // 비밀번호
// 보내는 사람
String fromEmail = "보내는사람@메일.com";
String fromName = "보내는사람 이름";
// email 전송
try {
HtmlEmail mail = new HtmlEmail();
mail.setDebug(true);
mail.setCharset(charSet);
mail.setSSLOnConnect(true); // SSL 사용 (TLS가 없는 경우 SSL 사용)
mail.setHostName(hostSMTP);
mail.setSmtpPort(587); // SMTP 포트 번호
mail.setAuthentication(hostSMTPid, hostSMTPpwd);
mail.setStartTLSEnabled(true); // TLS 사용
mail.addTo(email);
mail.setFrom(fromEmail, fromName, charSet);
mail.setSubject(subject);
mail.setHtmlMsg(msg);
mail.send();
} catch (Exception e) {
e.printStackTrace();
}
}
}
인증코드 보내기
인증코드는 FindUtil이라는 클래스를 생성해서 무작위로 랜덤 키를 생성하도록 했다.
public static String createKey() throws Exception {
StringBuffer key = new StringBuffer();
Random rnd = new Random();
for (int i = 0; i < 10; i++) {
int index = rnd.nextInt(3);
switch (index) {
case 0:
key.append((char) ((int) (rnd.nextInt(26)) + 97));
break;
case 1:
key.append((char) ((int) (rnd.nextInt(26)) + 65));
break;
case 2:
key.append((rnd.nextInt(10)));
break;
}
}
return key.toString();
}
그런데 생각해보니 그냥 UUID를 생성하는 편이 나았을텐데 굳이 왜 이렇게 했지..
컨트롤러에서 인증키를 생성해 세션에 올려두고 입력받은 이메일로 인증키를 보냈다.
xxxxxxxxxx
String keyCode = FindUtil.createKey();
session.setAttribute("keyCode", keyCode);
String subject = "[MIN-HA!] 비밀번호 찾기 인증코드 안내";
String msg = "";
msg += "<div align='center' style='border:1px solid black; font-family:verdana'>";
msg += "<h3 style='color: blue;'>비밀번호 찾기 인증코드입니다.</h3>";
msg += "<div style='font-size: 130%'>";
msg += "비밀번호 찾기 페이지로 돌아가 인증코드 <strong>"
msg += keyCode + "</strong> 를 입력해주세요.</div><br/>";
MailUtil.sendMail(mem_email, subject, msg);
이부분을 실행하면 메일이 이렇게 전송된다.
비밀번호 찾기
임시 비밀번호를 생성하는 방법을 찾는데 뭔가 마땅한게 이것밖에 없었다.. 마음엔 들지 않는데.. UUID로 생성하니 영문자와 숫자 조합만 나와서.. 특수문자를 넣고싶었고.. 그러고보니 이땐 UUID 쓸생각 했는데 위에서는 왜 저렇게했지
x
public static String getNewPwd() throws Exception {
char[] charSet = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
'W', 'X', 'Y', 'Z',
'!', '@', '#', '$', '%', '^', '&', '+', '=', '.'};
StringBuffer newKey = new StringBuffer();
for (int i = 0; i < 10; i++) {
int idx = (int) (charSet.length * Math.random());
newKey.append(charSet[idx]);
}
return newKey.toString();
}
컨트롤러에서 세션에 저장된 인증번호를 확인하고 일치하면 DB에 저장된 계정의 비밀번호를 임시비밀번호로 변경하고 임시 비밀번호를 생성해서 보냈다.
x
value = "/findPwd", method = RequestMethod.POST) (
public String findPwd(String mem_email, String mem_id, String inputCode, HttpSession session) throws Exception {
String keyCode = (String) session.getAttribute("keyCode");
if (!inputCode.equals(keyCode)) {
return "discordance";
}
session.removeAttribute("keyCode");
String newPwd = FindUtil.getNewPwd();
service.changePwd(newPwd, mem_id);
String subject = "[MIN-HA!] 임시 비밀번호 발급 안내";
String msg = "";
msg += "<div align='center' style='border:1px solid black; font-family:verdana'>";
msg += "<h3 style='color: blue;'><strong>" + mem_id
msg += "님</strong>의 임시 비밀번호 입니다. 로그인 후 비밀번호를 변경하세요.</h3>";
msg += "<p>임시 비밀번호 : <strong>" + newPwd + "</strong></p></div>";
MailUtil.sendMail(mem_email, subject, msg);
return "success";
}
보낸 메일은 이렇게 도착한다.
다들 비밀번호 변경을 무사히 할 수 있기를 바란다.
나는 설정을 잘못해서 계속 에러나서 하루 버림
'공부 > web' 카테고리의 다른 글
[jQuery/datepicker] 특정일 비활성화(disabled) 하기 (0) | 2018.09.04 |
---|---|
쿠키와 세션 (0) | 2018.07.20 |
[HTTP] GET vs POST (0) | 2018.07.14 |
웹서버 vs WAS (0) | 2018.05.31 |
[MyBatis] '${필드명}'과 '#{필드명}' (0) | 2018.05.31 |
댓글