본문으로 바로가기

 

Google STMP

-학교에서 진행하는 프로젝트에서 비밀번호 찾기를 구현하면서 알게된 방법이다.


 

개발환경

  • IntelliJ
  • JPA
  • SpringBoot
  • Gradle 

 

 *준비작업

1.

여기를 클릭해서 보안 수준이 낮은 앱의 액세스를 [허용] 으로 변경해야 합니다.

2. gradle 의존성을 추가합니다..

implementation 'org.springframework.boot:spring-boot-starter-mail'

 

*maven을 사용한다면  아래 코드를 추가합니다.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
    <version>1.4.3.RELEASE</version>
</dependency>

 

 

3. application.yml에 아래 내용 추가합니다. (git 커밋할때 아래 정보가 유출되지 않도록 주의!)

spring:
     mail:
    	host: smtp.gmail.com
    	port: 587
   	 	username: 본인의 구글 계정 @gmail.com
    	password: 본인의 구글 계정 비밀번호
    	properties:
      	mail.smtp.auth: true
      	mail.smtp.starttls.enable: true

-view

<div class="container">
    <!-- Modal -->
    <div class="modal fade" id="myModal" role="dialog">
        <div class="modal-dialog">

            <!-- Modal content-->
            <div class="modal-content">
                <div class="modal-header" style="padding:35px 50px;">
                    <h4><span class="glyphicon glyphicon-lock"></span> 비밀번호 찾기</h4>
                </div>
                <div class="modal-body" style="padding:40px 50px;">
                    <div style="color: #ac2925">
                        <center>입력된 정보로 임시 비밀번호가 전송됩니다.</center>
                    </div>
                    <hr>
                    <form role="form">
                        <div class="form-group">
                            <label for="userEmail"><span class="glyphicon glyphicon-user"></span>email</label>
                            <input type="text" class="form-control" id="userEmail" placeholder="가입시 등록한 이메일을 입력하세요.">
                        </div>
                        <div class="form-group">
                            <label for="userName"><span class="glyphicon glyphicon-eye-open"></span> name</label>
                            <input type="text" class="form-control" id="userName" placeholder="가입시 등록한 이름을 입력하세요.">
                        </div>
                        <button type="button" class="btn btn-success btn-block" id="checkEmail">OK</button>
                    </form>
                    <hr>
                    <div class="text-center small mt-2" id="checkMsg" style="color: red"></div>
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-danger btn-default pull-left" data-dismiss="modal"><span
                            class="glyphicon glyphicon-remove"></span> Cancel
                    </button>
                </div>
            </div>

        </div>
    </div>
</div>

 

-script (ajax를 이용했습니다.)

<script>

    $('.modal').on('hidden.bs.modal', function (e) {
        console.log('modal close');
        $(this).find('form')[0].reset()
    });

    $("#checkEmail").click(function () {
        let userEmail = $("#userEmail").val();
        let userName = $("#userName").val();

        $.ajax({
            type: "GET",
            url: "/check/findPw",
            data: {
                "userEmail": userEmail,
                "userName": userName
            },
            success: function (res) {
                if (res['check']) {
                    swal("발송 완료!", "입력하신 이메일로 임시비밀번호가 발송되었습니다.", "success").then((OK) = > {
                        if(OK) {
                            $.ajax({
                                type: "POST",
                                url: "/check/findPw/sendEmail",
                                data: {
                                    "userEmail": userEmail,
                                    "userName": userName
                                }
                            })
                            window.location = "/login";
                        }


                    }
                )
                    $('#checkMsg').html('<p style="color:darkblue"></p>');
                } else {
                    $('#checkMsg').html('<p style="color:red">일치하는 정보가 없습니다.</p>');
                }
            }
        })
    })
</script>

-비밀번호 찾기 view에서 Email과 name을 입력받고, ajax를 통해 controller로 Email과 name의 일치여부를 리턴합니다.

-일치하는 정보라면 이메일 전송을 담당하는 컨트롤러에 요청을 보내고, 일치하지 않는다면 메시지를 띄웁니다.


controller

 //Email과 name의 일치여부를 check하는 컨트롤러
 @GetMapping("/check/findPw")
    public @ResponseBody Map<String, Boolean> pw_find(String userEmail, String userName){
        Map<String,Boolean> json = new HashMap<>();
        boolean pwFindCheck = userService.userEmailCheck(userEmail,userName);

        System.out.println(pwFindCheck);
        json.put("check", pwFindCheck);
        return json;
    }

//등록된 이메일로 임시비밀번호를 발송하고 발송된 임시비밀번호로 사용자의 pw를 변경하는 컨트롤러
    @PostMapping("/check/findPw/sendEmail")
    public @ResponseBody void sendEmail(String userEmail, String userName){
        MailDto dto = sendEmailService.createMailAndChangePassword(userEmail, userName);
        sendEmailService.mailSend(dto);

    }

UserService

public boolean userEmailCheck(String userEmail, String userName) {

        User user = userRepository.findUserByUserId(userEmail);
        if(user!=null && user.getName().equals(userName)) {
            return true;
        }
        else {
            return false;
        }
    }

-Email을 통해 해당 email로 가입된 정보가 있는지 확인하고, 가입된 정보가 있다면 입력받은 name과 등록된 name이 일치한지 여부를 리턴하는 메소드

 

발송할 이메일 내용(정보)를 저장할 Dto 생성

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
public class MailDto {
    private String address;
    private String title;
    private String message;
}

 

 

SendEmailService

@Service
@AllArgsConstructor
public class SendEmailService{

    @Autowired
    UserRepository userRepository;

    private JavaMailSender mailSender;
    private static final String FROM_ADDRESS = "본인의 이메일 주소를 입력하세요!";



    public MailDto createMailAndChangePassword(String userEmail, String userName){
        String str = getTempPassword();
        MailDto dto = new MailDto();
        dto.setAddress(userEmail);
        dto.setTitle(userName+"님의 HOTTHINK 임시비밀번호 안내 이메일 입니다.");
        dto.setMessage("안녕하세요. HOTTHINK 임시비밀번호 안내 관련 이메일 입니다." + "[" + userName + "]" +"님의 임시 비밀번호는 "
        + str + " 입니다.");
        updatePassword(str,userEmail);
        return dto;
    }

    public void updatePassword(String str,String userEmail){
        String pw = EncryptionUtils.encryptMD5(str);
        int id = userRepository.findUserByUserId(userEmail).getId();
        userRepository.updateUserPassword(id,pw);
    }


    public String getTempPassword(){
        char[] charSet = new char[] { '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' };

        String str = "";

        int idx = 0;
        for (int i = 0; i < 10; i++) {
            idx = (int) (charSet.length * Math.random());
            str += charSet[idx];
        }
        return str;
    }

createMailAndChangePassword : DTO에 사용자가 원하는 내용과 제목을 저장

updatePassword : 이메일로 발송된 임시비밀번호로 해당 유저의 패스워드 변경

->EncryptionUtils.encryptMD5(str) 는 비밀번호 암호화이다. (참고 : https://1-7171771.tistory.com/82)

getTempPassword : 10자리의 랜덤난수를 생성하는 메소드

 

 

STMP mailSend

  public void mailSend(MailDto mailDto){
        System.out.println("이멜 전송 완료!");
        SimpleMailMessage message = new SimpleMailMessage();
        message.setTo(mailDto.getAddress());
        message.setFrom(SendEmailService.FROM_ADDRESS);
        message.setSubject(mailDto.getTitle());
        message.setText(mailDto.getMessage());

        mailSender.send(message);
    }

 

setTo() : 받는사람 주소

setFrom() : 보내는 사람 주소  (설정하지 않으면 디폴트 값인  yml에 작성한 username) 

setSubject() : 메일 제속

setText() : 메일 내용

추가 기능은 문서 를 참고하세요.

 


결과