ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [๊ตฌํ˜„] ์Šคํ”„๋ง์œผ๋กœ ์ด๋ฉ”์ผ ์ธ์ฆ ์ฝ”๋“œ ๋ฐœ๊ธ‰, ์ธ์ฆํ•˜๊ธฐ
    SPRING/PROJECT 2021. 12. 12. 22:15

    ๊ณต๋ถ€ํ•˜๋ฉด์„œ ๋งŒ๋“ค์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ‹€๋ฆฐ ๋ถ€๋ถ„์ด๋‚˜ ๋” ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

     

    ๊ตฌํ˜„ ํ•  ๋‚ด์šฉ

    1)

    • ๋ฉ”์ผ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ ๋‹ค.
    • ํ•ด๋‹น ๋ฉ”์ผ๋กœ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ๋ณด๋‚ธ๋‹ค.

    2)

    • ๋ฉ”์ผ๋กœ ์˜จ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•œ๋‹ค.
    • ๋ฉ”์ผ๊ณผ ์ธ์ฆ ์ฝ”๋“œ ์ผ์น˜ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•œ๋‹ค.

     

    1. ์•„์ด๋”” ๋งŒ๋“ค๊ธฐ

    ๋‚˜๋Š” Gmail SMTP Server๋ฅผ ์ด์šฉํ•  ๊ฒƒ์ด๋‹ค.

    ๊ฐœ์ธ ์ด๋ฉ”์ผ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋Š” ์ข€ ๊ทธ๋ ‡๊ธฐ์— ์ƒˆ๋กœ์šด ๊ณ„์ •์„ ํ•˜๋‚˜ ๋” ๋งŒ๋“ค๊ฒƒ์ด๋‹ค.

    ๊ณ„์ •์˜ ๋ณด์•ˆ์ด ๋‚ฎ์€ ์•ฑ์˜ ์•ก์„ธ์Šค๋ฅผ ํ—ˆ์šฉํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

     

    2. Gmail SMTP Server ์„ค์ •

    build.gradleํŒŒ์ผ์˜ dependencies์— ๋‹ค์Œ ๋ฌธ์žฅ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

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

     

    application.propertiesํŒŒ์ผ์— ๋‹ค์Œ ๋ฌธ์žฅ์„ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค.

    spring.mail.host=smtp.gmail.com
    spring.mail.port=587
    spring.mail.username=(email)
    spring.mail.password=(password)
    spring.mail.properties.mail.smtp.starttls.enable=true
    spring.mail.properties.mail.smtp.auth=true

    email, password๋Š” ๋ณธ์ธ ๊ฒƒ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

     

    3. ์ธ์ฆ ์ฝ”๋“œ ๋„๋ฉ”์ธ ์—”ํ‹ฐํ‹ฐ ๋งŒ๋“ค๊ธฐ

    verifycode๋Š” ์ฝ”๋“œ๊ฐ’๊ณผ ์ฝ”๋“œ์˜ ์ด๋ฉ”์ผ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

    ์ฝ”๋“œ๋Š” ์ž๋™์ƒ์„ฑ์ด๋ฉฐ ์ด๋ฉ”์ผ๊ณผ ์ฝ”๋“œ๊ฐ€ ๋งž๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•จ์ด๋‹ค.

    @Getter
    @Entity
    @Table
    @AllArgsConstructor
    @NoArgsConstructor
    public class VerifyCode extends Timestamped{
    
        @Id
        @Column(name = "code")
        @GeneratedValue(generator = RandomGenerator.generatorName)
        @GenericGenerator(name = RandomGenerator.generatorName, strategy = "com.moment.CapturedMomentServer.util.RandomGenerator")
        String code;
    
        @Column(name = "email", unique = true)
        String email;
    
        public VerifyCode(VerifyCodeDto dto){
            this.email = dto.getEmail();
        }
    }

    randomgenerator๋Š” ๋‹ค๋ฅธ ๋ถ„์ด ์ธํ„ฐ๋„ท์— ์˜ฌ๋ ค์ฃผ์‹  ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

    http://daplus.net/java-%EC%9E%84%EC%9D%98%EC%9D%98-%EC%98%81%EC%88%AB%EC%9E%90-%EB%AC%B8%EC%9E%90%EC%97%B4%EC%9D%84-%EC%83%9D%EC%84%B1%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9E%85/

     

    [java] ์ž„์˜์˜ ์˜์ˆซ์ž ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ? - ๋ฆฌ๋ทฐ๋‚˜๋ผ

    ๋‚˜๋Š” ์ฐพ๊ณ  ์žˆ์—ˆ๋‹ค ์˜์‚ฌ ๋‚œ์ˆ˜ ์˜์ˆซ์ž ๋ฌธ์ž์—ด์„ ์ƒ์„ฑํ•˜๋Š” ๊ฐ„๋‹จํ•œ Java ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚ด ์ƒํ™ฉ์—์„œ ๊ทธ๊ฒƒ์€ 500K+์„ธ๋Œ€๋ฅผ ์ดˆ์›”ํ•˜์—ฌ “์•„๋งˆ๋„”๋…์ฐฝ์  ์ธ ๊ณ ์œ  ์„ธ์…˜ / ํ‚ค ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค (ํ•„

    daplus.net

    ์ธํ„ฐ๋„ท์— ๋งŽ์ด ๋„๋Š” ์ฝ”๋“œ ๊ฐ™๊ธด ํ•œ๋ฐ ์ด๋Ÿฐ ์ฝ”๋“œ๋ฅผ ์ฐธ๊ณ ํ–ˆ๊ณ  12์ž์˜ ๋žœ๋ค ๋ฌธ์ž๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

    UUID๋Š” ๋„ˆ๋ฌด ๊ธธ์–ด์„œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

     

    ์ฒ˜์Œ์—๋Š” ์ด๋ฉ”์ผ๋งŒ์„ ์ž…๋ ฅํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ์ž๋™์ƒ์„ฑ ๋ฐœ๊ธ‰๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ DTO๋ฅผ ๋งŒ๋“ค๋„๋ก ํ•˜๊ฒ ๋‹ค.

    @Getter
    @Setter
    @AllArgsConstructor
    @NoArgsConstructor
    public class VerifyCodeDto {
        @NotNull
        private String email;   // ํšŒ์› ๋‹‰๋„ค์ž„
    }

     

    4. ์ปจํŠธ๋กค๋Ÿฌ ๋งŒ๋“ค๊ธฐ

    ์ธ์ฆ ์ฝ”๋“œ ๋ฉ”์ผ ์ „์†ก ์ปจํŠธ๋กค๋Ÿฌ๋ถ€ํ„ฐ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ๋‹ค.

        @PostMapping(value = "/user/certification")
        public ResponseEntity<HashMap> mailCheck(@RequestBody VerifyCodeDto codeDto){
            
            //์ฝ”๋“œ ์ƒ์„ฑ & ์ €์žฅ
            VerifyCode verifyCode = verifyCodeService.saveCode(codeDto);
            
            //๋ฉ”์ผ ์ „์†ก
            boolean success = mailService.checkEmail(verifyCode);
    
            HashMap<String, Object> responseMap = new HashMap<>();
            if(success) {
                responseMap.put("status", 200);
                responseMap.put("message", "๋ฉ”์ผ ๋ฐœ์†ก ์„ฑ๊ณต");
                responseMap.put("code" , verifyCode.getCode());
                return new ResponseEntity<HashMap> (responseMap, HttpStatus.OK);
            }
            else{
                responseMap.put("status", 500);
                responseMap.put("message", "๋ฉ”์ผ ๋ฐœ์†ก ์‹คํŒจ");
                return new ResponseEntity<HashMap> (responseMap, HttpStatus.CONFLICT);
            }
        }

    verifyCodeService์—์„œ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด ์ €์žฅํ•œ๋‹ค.

    ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ mailService์—์„œ ์ด๋ฉ”์ผ๋กœ ์ „์†กํ•œ๋‹ค.

     

    5. VerifyCodeRepository

    @Repository
    public interface VerifyCodeRepository extends JpaRepository<VerifyCode, Long> {
        public VerifyCode findByEmail(String email);
        public VerifyCode findByCode(String code);
        public boolean existsByEmail(String email);
        public void deleteByEmail(String email);
    }

    6. VerifyCodeService

    @Service
    @Transactional
    @AllArgsConstructor
    public class VerifyCodeService {
    
        private final VerifyCodeRepository repository;
    
        ...
    
        public VerifyCode saveCode(VerifyCodeDto code){
            if(repository.existsByEmail(code.getEmail()))
                repository.deleteByEmail(code.getEmail());
            return repository.save(new VerifyCode(code));
        }
        ...
    }

    (์ด๋ฉ”์ผ๋งŒ ๋“ค์–ด์žˆ๋Š”) VerifyCodeDto๋ฅผ ๋ฐ›์•„์„œ

    ์ธ์ฆ ์ฝ”๋“œ๊ฐ€ ๋ฐœ๊ธ‰๋˜์–ด์žˆ๋Š” ์ด๋ฉ”์ผ์ธ์ง€ ํ™•์ธํ•œ๋‹ค.

    ๋ฐœ๊ธ‰๋˜์–ด ์žˆ๋‹ค๋ฉด, ๊ทธ ์ธ์ฆ์ฝ”๋“œ๋Š” ์‚ญ์ œํ•œ๋‹ค.

    ๊ทธ๋ฆฌ๊ณ  ์—ฌํŠผ ๋ฐ›์€ ์ด๋ฉ”์ผ๋กœ new VerifyCode๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ƒˆ ์ธ์ฆ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

     

    7. MailService

    @Service
    @RequiredArgsConstructor
    public class MailService {
    
        private final JavaMailSender javaMailSender;
        private final PasswordEncoder passwordEncoder;
    
        public boolean checkEmail(VerifyCode verifyCode){
    
            if(verifyCode.getCode() == null)
                return false;
    
            SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
            simpleMailMessage.setTo(verifyCode.getEmail());
            simpleMailMessage.setSubject("Captured-Moment ์ด๋ฉ”์ผ ํ™•์ธ ์ฝ”๋“œ");
            simpleMailMessage.setText("์ €ํฌ ์„œ๋น„์Šค์— ๊ฐ€์ž…ํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค.\n"
            + "์ด๋ฉ”์ผ ํ™•์ธ ์ฝ”๋“œ๋Š” " + verifyCode.getCode() + " ์ž…๋‹ˆ๋‹ค.");
    
            javaMailSender.send(simpleMailMessage);
            return true;
        }
        ...
    }

    JavaMailSender๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

    To, Subject(์ œ๋ชฉ), ๋ณด๋‚ผ Text๋ฅผ ์„ค์ •ํ•œ๋‹ค.

    ๋‚ด์šฉ์€ ์ € ์ฝ”๋“œ์™€ ๊ฐ™์ด ์„ค์ •ํ•œ๋‹ค.

     

    8. ํ…Œ์ŠคํŠธ

    ๋‘๊ทผ...โค ์ง„์งœ ์™€์žˆ๋‹ค

     

     

    9. ์ปจํŠธ๋กค๋Ÿฌ

    ๋‹ค์Œ์€ ์ž…๋ ฅ๋ฐ›์€ ์ฝ”๋“œ๊ฐ€ ์ด ์ด๋ฉ”์ผ๊ณผ ๋งž๋Š” ์ฝ”๋“œ์ธ์ง€ ํ™•์ธํ•˜๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋‹ค.

        @GetMapping(value = "/user/check")
        public ResponseEntity<HashMap> mailCheck(@RequestBody VerifyCode verifyCode){
    
            boolean check = verifyCodeService.check(verifyCode);
            HashMap<String, Object> responseMap = new HashMap<>();
    
            if(check){
                verifyCodeService.deleteByEmail(verifyCode.getEmail());
                responseMap.put("status", 200);
                responseMap.put("message", "์ธ์ฆ ์„ฑ๊ณต");
                return new ResponseEntity<HashMap> (responseMap, HttpStatus.OK);
            }
            else{
                responseMap.put("status", 401);
                responseMap.put("message", "์ž˜๋ชป๋œ ์ธ์ฆ ์ฝ”๋“œ");
                return new ResponseEntity<HashMap> (responseMap, HttpStatus.CONFLICT);
            }
        }

    ๋งž๋Š”์ง€ ์ฒดํฌํ•˜๊ณ  ๋งž๋‹ค๋ฉด ์ธ์ฆ์„ฑ๊ณต, ํ‹€๋ฆฌ๋‹ค๋ฉด ์ธ์ฆ ์ฝ”๋“œ๊ฐ€ ํ‹€๋ ธ๋‹ค๋Š” ๋ฉ”์„ธ์ง€๊ฐ€ ๋‚˜์˜จ๋‹ค.

    ๋˜ํ•œ ์ธ์ฆ์ด ์„ฑ๊ณตํ•œ๋‹ค๋ฉด ํ•ด๋‹น ์ธ์ฆ์ฝ”๋“œ๋Š” ์ง€์›Œ๋ฒ„๋ฆฐ๋‹ค. ๋” ์ด์ƒ ์“ธ๋ชจ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

     

    10. VerifyCodeService

    @Service
    @Transactional
    @AllArgsConstructor
    public class VerifyCodeService {
    
        private final VerifyCodeRepository repository;
    
        public boolean check(VerifyCode code){
            VerifyCode findCode = repository.findByEmail(code.getEmail());
            if(findCode == null)
                return false;
            else if(code.getCode().equals(findCode.getCode()))
                return true;
            else
                return false;
        }
        
        public void deleteByEmail(String email){
            repository.deleteByEmail(email);
        }
    }

    ์ž…๋ ฅ๋œ ์ด๋ฉ”์ผ๋กœ ํ•ด๋‹นํ•˜๋Š” ์ฝ”๋“œ/์ด๋ฉ”์ผ ์„ธํŠธ (VerifyCode)๋ฅผ ์ฐพ์•„์˜จ๋‹ค.

    ์ฐพ์•„์˜ค์ง€ ๋ชปํ–ˆ์œผ๋ฉด false๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

    ์ž…๋ ฅ๋œ ์ฝ”๋“œ์™€ ์ฐพ์€ ์ฝ”๋“œ๊ฐ€ ๊ฐ™์œผ๋ฉด true๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

    ๋‘˜๋‹ค ์•„๋‹ˆ๋ฉด false๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

     

    11. ํ…Œ์ŠคํŠธ

    ์ž˜๋ชป๋œ๊ฑฐ ์ž…๋ ฅํ•˜๋ฉด ์ธ์ฆ ์•ˆ๋˜๊ณ , ํ•œ๋ฒˆ ๋” sendํ•ด๋„ ์ธ์ฆ ์•ˆ๋œ๋‹ค.(์ง€์›Œ๋ฒ„๋ ค์„œ) ๋!

Designed by Tistory.