본문 바로가기
web/Bakery Shop Project

쇼핑몰 구현 15 - 메일 인증 기능

by su0a 2024. 2. 23.

1. MailSendService

@Service
public class MailSendService {
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private RedisUtil redisUtil;
    private int authNumber;

    public boolean checkAuthNum(String email, String authNum){
        if(redisUtil.getData(authNum)==null){
            System.out.println("authNum=null");
            return false;
        }
        else if(redisUtil.getData(authNum).equals(email)){
            return true;
        }
        else{
            System.out.println(redisUtil.getData(authNum));
            System.out.println(email);
            return false;
        }
    }
    //임의의 6자리 양수 반환
    public void makeRandomNumber(){
        Random r = new Random();
        String randomNumber="";
        for(int i=0;i<6;i++){
            randomNumber+=Integer.toString(r.nextInt(10));
        }
        authNumber=Integer.parseInt(randomNumber);
    }
    
    //mail을 어디서 보내는지, 어디로 보내는지 , 인증 번호를 html 형식으로 어떻게 보내는지 작성
    public String joinEmail(String email) {
        makeRandomNumber();
        String setFrom = "tjddk1581@gmail.com"; // email-config에 설정한 자신의 이메일 주소를 입력
        String toMail = email;
        String title = "회원 가입 인증 이메일 입니다."; // 이메일 제목
        String content =
                "bakery shop을 방문해주셔서 감사합니다." +  //html 형식으로 작성 !
                        "<br><br>" +
                        "인증 번호는 " + authNumber + "입니다." +
                        "<br>" +
                        "인증번호를 제대로 입력해주세요"; //이메일 내용 삽입
        mailSend(setFrom, toMail, title, content);
        return Integer.toString(authNumber);
    }

    //이메일 전송
    public void mailSend(String setFrom, String toMail, String title, String content) {
        MimeMessage message = mailSender.createMimeMessage();//JavaMailSender 객체를 사용하여 MimeMessage 객체를 생성
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");//이메일 메시지와 관련된 설정을 수행합니다.
            // true를 전달하여 multipart 형식의 메시지를 지원하고, "utf-8"을 전달하여 문자 인코딩을 설정
            helper.setFrom(setFrom);//이메일의 발신자 주소 설정
            helper.setTo(toMail);//이메일의 수신자 주소 설정
            helper.setSubject(title);//이메일의 제목을 설정
            helper.setText(content,true);//이메일의 내용 설정 두 번째 매개 변수에 true를 설정하여 html 설정으로한다.
            mailSender.send(message);
        } catch (MessagingException e) {//이메일 서버에 연결할 수 없거나, 잘못된 이메일 주소를 사용하거나, 인증 오류가 발생하는 등 오류
            // 이러한 경우 MessagingException이 발생
            e.printStackTrace();//e.printStackTrace()는 예외를 기본 오류 스트림에 출력하는 메서드
        }
        redisUtil.setDataExpire(Integer.toString(authNumber),toMail,60*5L);

    }


}

 

2. RedisUtil

  • 메일 인증 키를 임시로 저장하기 위해
@Service
@RequiredArgsConstructor
public class RedisUtil {
    private final StringRedisTemplate redisTemplate;//Redis에 접근하기 위한 Spring의 Redis 템플릿 클래스

    public String getData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 가져오는 메서드
        ValueOperations<String,String> valueOperations=redisTemplate.opsForValue();
        return valueOperations.get(key);
    }
    public void setData(String key,String value){//지정된 키(key)에 값을 저장하는 메서드
        ValueOperations<String,String> valueOperations=redisTemplate.opsForValue();
        valueOperations.set(key,value);
    }
    public void setDataExpire(String key,String value,long duration){//지정된 키(key)에 값을 저장하고, 지정된 시간(duration) 후에 데이터가 만료되도록 설정하는 메서드
        ValueOperations<String,String> valueOperations=redisTemplate.opsForValue();
        Duration expireDuration=Duration.ofSeconds(duration);
        valueOperations.set(key,value,expireDuration);
    }
    public void deleteData(String key){//지정된 키(key)에 해당하는 데이터를 Redis에서 삭제하는 메서드
        redisTemplate.delete(key);
    }
}

 

3. MailController

@RestController
@RequiredArgsConstructor
@RequestMapping("/mail")
public class MailController {
    private final MailSendService mailService;
    @PostMapping("/mailSend")
    public String mailSend(@RequestBody @Valid EmailRequestDto emailDto){
        System.out.println("이메일 인증 요청이 들어옴");
        System.out.println("이메일 인증 이메일 :"+emailDto.getEmail());
        return mailService.joinEmail(emailDto.getEmail());
    }
    @PostMapping("/mailAuthCheck")
    public ResponseEntity<String> AuthCheck(@RequestBody @Valid EmailCheckDto emailCheckDto){
        boolean checked = mailService.checkAuthNum(emailCheckDto.getEmail(), emailCheckDto.getAuthNum());
        try {
            if (checked) {
                return ResponseEntity.ok("ok");
            } else {
                return ResponseEntity.badRequest().body("인증번호 일치하지 않음");
            }
        }catch (AuthNumCheckException e){
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("AuthNum 검증 오류: "+e.getMessage());
        }

    }
}

 

4. EmailCheckDto

  • 이메일 인증하기 위한 DTO
@Data
public class EmailCheckDto {
    @Email
    @NotEmpty(message="이메일을 입력해주세요")
    private String email;

    @NotEmpty(message = "인증번호를 입력해주세요")
    private String authNum;
}

 

5. EmailRequestDto

@Getter
@Setter
public class EmailRequestDto {
    @Email
    @NotEmpty(message = "이메일을 입력해주세요")
    private String email;
}