저번에 Laravel 로 이메일 인증코드를 구현하는 방법을 알아보았다.
https://normal-operating.tistory.com/37
Laravel 이메일 인증코드 구현
https://normal-operating.tistory.com/36 Laravel 이메일 인증 연동 구현하기회사에서 레거시만 사용하다보니 기능을 간단하게 구현할 수 있는 laravel 을 통해서 구현해보았다. 진행하면서 발생한 오류
normal-operating.tistory.com
기능은 거의 비슷하다.
Redis 설치
https://jaey0ng.tistory.com/54
[Redis] 윈도우 환경에서 redis 설치/실행하기
윈도우 설치 Redis 공식문서입니다. https://redis.io/docs/install/install-redis/install-redis-on-windows/ Install Redis on Windows Use Redis on Windows for development redis.io 레디스 공식문서에는 위처럼 사용하면 된다라고 써
jaey0ng.tistory.com
다른 점은 Redis 를 사용해서 인증번호를 저장하고 인증번호를 이메일로 전송해준다는 점
설정사항
1. SecurityConfig 에 인증 관련 경로인
"/api/email/send",
를 추가해준다
.requestMatchers("/login", "/register","/api/register", "/api/email/send", "/verify").permitAll() // 인증 관련 경로는 누구나 접근 가능
2. application.properties 에 다음과 같이 설정 추가
spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=인증받은gmail
spring.mail.password=16자리-없이
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.writetimeout=5000
spring.mail.transport.protocol=smtp
3.build.gradle의 dependencies에 다음과 같이 설정 추가
implementation 'org.springframework.boot:spring-boot-starter-mail'
4. MailConfig 생성 후
package com.application.member.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import java.util.Properties;
@Configuration
public class MailConfig {
@Bean
public JavaMailSender getJavaMailSender() {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername("이메일");
mailSender.setPassword("인증코드16자리-없이");
Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.debug", "true");
// SSL 설정 추가
props.put("mail.smtp.ssl.trust", "smtp.gmail.com");
props.put("mail.smtp.ssl.protocols", "TLSv1.2");
return mailSender;
}
}
다음과 같이 코드 작성
5. RedisConfig 에
package com.application.member.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
@Configuration
public class RedisConfig {
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate(connectionFactory);
}
}
다음과 같이 코드 작성
6. EmailService에
@Service
public class EmailService {
private final JavaMailSender mailSender;
private final StringRedisTemplate redisTemplate;
public EmailService(JavaMailSender mailSender, StringRedisTemplate redisTemplate) {
this.mailSender = mailSender;
this.redisTemplate = redisTemplate;
}
// 인증번호 생성
public String generateVerificationCode() {
Random random = new Random();
int code = 100000 + random.nextInt(900000); // 6자리 랜덤 숫자
return String.valueOf(code);
}
// 인증번호 Redis에 저장 (5분 유효기간 설정)
public void saveVerificationCode(String email, String verificationCode) {
ValueOperations<String, String> ops = redisTemplate.opsForValue();
ops.set(email, verificationCode, 5, TimeUnit.MINUTES); // 5분 TTL
}
// 인증번호 검증
public boolean verifyCode(String email, String code) {
ValueOperations<String, String> ops = redisTemplate.opsForValue();
String storedCode = ops.get(email);
if (storedCode != null && storedCode.equals(code)) {
redisTemplate.delete(email); // 인증 성공 시 Redis에서 제거
return true;
}
return false;
}
// 이메일 발송
public void sendVerificationEmail(String toEmail, String verificationCode) {
MimeMessage message = mailSender.createMimeMessage();
try {
message.setFrom(toEmail);
message.setRecipients(MimeMessage.RecipientType.TO, toEmail);
String body = "";
body += "<h3>" + "요청하신 인증 번호입니다." + "</h3>";
body += "<h1>" + verificationCode + "</h1>";
body += "<h3>" + "감사합니다." + "</h3>";
message.setText(body,"UTF-8", "html");
mailSender.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
다음과 같이 코드작성
7. EmailController 에
@RestController
@RequestMapping("/api/email")
public class EmailController {
private final EmailService emailService;
public EmailController(EmailService emailService) {
this.emailService = emailService;
}
@PostMapping("/send")
public String sendVerificationCode(@RequestParam String email) {
System.out.println("Received email: " + email);
String verificationCode = emailService.generateVerificationCode();
System.out.println("Generated Verification Code: " + verificationCode);
emailService.saveVerificationCode(email, verificationCode); // Redis에 저장
emailService.sendVerificationEmail(email, verificationCode); // 이메일 발송
return "인증번호가 발송되었습니다.";
}
다음과 같이 코드작성
프론트 코드
const email = document.getElementById("email").value;
const response = await fetch('/api/email/send', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ email })
});
Spring Security 때문에 고생좀 했다.
2일에 걸쳐서 구현하게 되어 빠져있는 부분이 있을 수 있습니다.
'취미 > 프로그래밍' 카테고리의 다른 글
AWS LightSail 도메인 연결 후 웹 서버 띄우기(1)(2025ver.) (0) | 2025.02.15 |
---|---|
Laravel Sail을 활용한 MySQL 설정과 개발환경 구축 (1) | 2025.01.03 |
Android Studio 패키지명 변경하기(톱니바퀴 없을 경우) (1) | 2024.11.13 |
Mysql User 더미데이터 넣는 프로시저 (3) | 2024.09.29 |
Laravel TDD 찍먹 (1) | 2024.09.11 |