Redis를 이용한 메일 인증

slee2·2022년 5월 31일
0

ToyProjectBoard

목록 보기
4/5

Redis는 초고속 성능을 갖고 있어 이메일 인증키를 다루기에 유용합니다.

이메일 인증을 할때, 인증을 하기 이전에 인증키를 가지고 있을 DB가 필요한데, 이를 위해 Member 엔티티에 컬럼을 추가하여 관리하는 것 보다는, Redis를 이용해 AuthKey를 관리하고 만료 시간을 정해주는 것이 유용해 보입니다.

Redis 설치

brew 를 이용한 설치

$> brew update
$> brew install redis

Redis 사용법

redis 키기
$> brew services start redis

redis 끄기
$> brew services stop redis

redis 재시작
$> brew services restart redis

CLI 접속
$> redis-cli
127.0.0.1:6379>

위와 같이 나온다면 스프링에서 설정할때
host : 127.0.0.1
port : 6379
가 됨

조회
127.0.0.1:6379> keys *
(empty array)

Redis 설정 + RedisTemplate 사용

application.yml

spring:
  redis:
    host: localhost
    port: 6379

RedisConfig

@Configuration
public class RedisConfig {

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

    @Value("${spring.redis.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(host, port);
    }

    @Bean
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

RedisTemplate를 사용하기 위해 위
public RedisTemplate<?, ?> redisTemplate()을 추가해줍니다.

AuthKeyService

@Component
@RequiredArgsConstructor
public class AuthKeyService {

    private final RedisTemplate<String, String> redisTemplate;

    public void saveAuth(String email, String authKey) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.set(email, authKey, 30, TimeUnit.MINUTES);
    }

    public void deleteAuth(String email) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        valueOperations.getAndDelete(email);
    }

    public boolean checkAuth(String email, String authKey) {
        ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
        String authK = valueOperations.getAndDelete(email);
        if (authK.equals(authKey)) return true;
        return false;
    }
}

간단하게 키 저장, 키 삭제, 키 확인 세 개의 메서드를 작성해봤습니다.
ValueOperations : map처럼 첫번째 값을 키로 지정하고, 두번째 값을 value로 저장하게 됩니다.
valueoprations.set() : 키, 값 만 저장할 수도 있고, 만료 기간까지 저장할 수도 있습니다. 만료기간의 경우 30, TimeUnit.MINUTES라면 30분이 지났을때 해당 키가 자동으로 삭제됩니다.

MailController

@PostMapping("/member/signUp/email")
public void signUp(@ModelAttribute MemberDto memberDto){
	// DB에 기본정보 insert
    memberService.signUp(memberDto);
    authKeyRepository.deleteAuth(memberDto.getEmail());

	//임의의 authKey 생성 & 이메일 발송
    String authKey = mss.sendAuthMail(memberDto.getEmail());
    authKeyRepository.saveAuth(memberDto.getEmail(), authKey);
}

처음에 이메일을 이용해 회원가입을 하게 될때, Member에는 이메일 인증 여부만 Boolean값으로 저장하게 되고, 혹시나 이메일 회원가입을 한번이 아니라 여러번 시도했을 경우를 대비해 미리 AuthKey가 있던 없던 지워줍니다.

이후에 authKey를 생성해준 후에 메일을 보내고 이메일을 keyauthKeyvalue로 새로운 redis 데이터를 저장해줍니다.

@GetMapping("member/signUpConfirm")
public String authEmail(@ModelAttribute AuthEmailDto authEmailDto) {
	boolean check = authKeyRepository.checkAuth(authEmailDto.getEmail(), authEmailDto.getAuthKey());
    if (check) {
    	memberService.successAuth(authEmailDto.getEmail());
        return "success";
    }
    return "false";
}

메일 인증을 누르게 되면, checkAuth에서 해당 authKey값이 맞는지 확인후 맞다면 Member 엔티티에서 인증 완료로 바꿔줍니다.

0개의 댓글