Redis
는 초고속 성능을 갖고 있어 이메일 인증키를 다루기에 유용합니다.이메일 인증을 할때, 인증을 하기 이전에 인증키를 가지고 있을 DB가 필요한데, 이를 위해
Member
엔티티에 컬럼을 추가하여 관리하는 것 보다는,Redis
를 이용해AuthKey
를 관리하고 만료 시간을 정해주는 것이 유용해 보입니다.
brew
를 이용한 설치
$> brew update
$> brew install 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)
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
를 생성해준 후에 메일을 보내고 이메일을 key
로 authKey
를 value
로 새로운 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
엔티티에서 인증 완료로 바꿔줍니다.