-
[๊ตฌํ] ์คํ๋ง์ผ๋ก ์ด๋ฉ์ผ ์ธ์ฆ ์ฝ๋ ๋ฐ๊ธ, ์ธ์ฆํ๊ธฐ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๋ ๋ค๋ฅธ ๋ถ์ด ์ธํฐ๋ท์ ์ฌ๋ ค์ฃผ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์๋ค.
[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ํด๋ ์ธ์ฆ ์๋๋ค.(์ง์๋ฒ๋ ค์) ๋!
'SPRING > PROJECT' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๊ตฌํ] Spring์์ Firebase ํธ์์๋ฆผ ๊ตฌํํ๊ธฐ (0) 2023.09.26 [๊ตฌํ] Spring์์ ์นด์นด์คํก ๋ก๊ทธ์ธ (0) 2023.09.25 [๊ตฌํ] Spring์์ ์๋ฌ๋ฅผ ๋ด๋ 3๊ฐ์ง ๋ฐฉ๋ฒ (2) 2023.04.02 [๊ตฌํ] ์คํ๋ง์ผ๋ก ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ๋งํฌ ๋ง๋ค๊ธฐ (0) 2021.12.12 [๋ฐฐํฌ] ์คํ๋ง ํ๋ก์ ํธ EC2๋ก AWS์ ๋ฐฐํฌํ๊ธฐ + RDS ๋ง๋ค๊ธฐ (0) 2021.12.09