Skip to content

Commit

Permalink
Merge pull request #52 from IoTeaTime/feature/51-kan-104-email-send
Browse files Browse the repository at this point in the history
feat: Redis를 활용한 이메일 인증 코드 발송 구현
  • Loading branch information
ywonchae1 authored Oct 31, 2024
2 parents b7cfc8e + c8c4597 commit 7288802
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package org.ioteatime.meonghanyangserver.auth.service;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ThreadLocalRandom;
import lombok.RequiredArgsConstructor;
import org.ioteatime.meonghanyangserver.auth.dto.reponse.LoginResponse;
import org.ioteatime.meonghanyangserver.auth.dto.reponse.RefreshResponse;
Expand All @@ -11,6 +15,8 @@
import org.ioteatime.meonghanyangserver.common.exception.ApiExceptionImpl;
import org.ioteatime.meonghanyangserver.common.utils.JwtUtils;
import org.ioteatime.meonghanyangserver.group.repository.groupuser.GroupUserRepository;
import org.ioteatime.meonghanyangserver.redis.EmailCode;
import org.ioteatime.meonghanyangserver.redis.EmailCodeRepository;
import org.ioteatime.meonghanyangserver.redis.RefreshToken;
import org.ioteatime.meonghanyangserver.redis.RefreshTokenRepository;
import org.ioteatime.meonghanyangserver.user.domain.UserEntity;
Expand All @@ -27,6 +33,7 @@ public class AuthService {
private final GoogleMailClient googleMailClient;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final JwtUtils jwtUtils;
private final EmailCodeRepository emailCodeRepository;
private final RefreshTokenRepository refreshTokenRepository;
private final GroupUserRepository groupUserRepository;

Expand Down Expand Up @@ -66,8 +73,32 @@ public UserSimpleResponse joinProcess(UserDto userDto) {
}

public void send(String email) {
// TODO. Redis 적용 후 코드 발급 구현 필요
googleMailClient.sendMail(email, "hello", "world");
String code = getCode();
emailCodeRepository.save(EmailCode.builder().email(email).code(code).build());
String mailSubject = "[\uD83D\uDC36 멍하냥] 이메일 인증 코드입니다.";
String mailContent =
"""
<h3>환영해요!</h3>
<b>인증코드를 입력하세요</b>
<p>%s</p>
"""
.formatted(code);
googleMailClient.sendMail(email, mailSubject, mailContent);
}

private static String getCode() {
ThreadLocalRandom random = ThreadLocalRandom.current();

List<String> authStr = new CopyOnWriteArrayList<>();
for (int i = 0; i < 3; i++) {
authStr.add(String.valueOf(random.nextInt(10)));
}
for (int i = 0; i < 3; i++) {
authStr.add(String.valueOf((char) (random.nextInt(26) + 65)));
}

Collections.shuffle(authStr);
return String.join("", authStr);
}

public UserSimpleResponse verifyEmail(String email) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public void sendMail(String toEmailAddress, String subject, String message) {
email.addRecipient(
javax.mail.Message.RecipientType.TO, new InternetAddress(toEmailAddress));
email.setSubject(subject);
email.setText(message);
email.setContent(message, "text/html;charset=utf-8");

// Encode and wrap the MIME message into a gmail message
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.ioteatime.meonghanyangserver.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisKeyValueAdapter;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;

@Configuration
@EnableRedisRepositories(
enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;

@Value("${spring.data.redis.password}")
private String password;

@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
redisConfiguration.setHostName(host);
redisConfiguration.setPort(6379);
redisConfiguration.setPassword(password);
return new LettuceConnectionFactory(redisConfiguration);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.ioteatime.meonghanyangserver.redis;

import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;

@Getter
@Builder
@AllArgsConstructor
@RedisHash(value = "emailCode", timeToLive = 60 * 3)
public class EmailCode {
@Id private Long id;

@Indexed private String email;

private String code;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.ioteatime.meonghanyangserver.redis;

import java.util.Optional;
import org.springframework.data.repository.CrudRepository;

public interface EmailCodeRepository extends CrudRepository<EmailCode, String> {
Optional<EmailCode> findByEmail(String email);
}

0 comments on commit 7288802

Please sign in to comment.