이전 글에서 구글 이메일을 연동하여 회원가입 시 인증번호를 보내는데까지 완료했다

 

이제 유저는 메일로 받은 인증번호를 가지고 인증 절차가 필요한데

서버에 인증번호를 어떻게 저장해야될지 찾아보다가  nosql redis 방법을 적용했다.

 

처음에는 http session을 적용하여 key,value 값으로 진행했었다.

여기까진 좋았으나 세션에 타임아웃(시간설정 ex:인증번호를 받고(+동시에 인증번호를 세션에 저장) 어느정도 시간이 지나면 인증번호 입력시간이 지낫음을 알리며 인증번호를 다시 받게하는 과정을 만들고싶었다)을 설정하면 세션에 담기는 모든 데이터들이 적용되어 만약 나중에 세션에 어떤게 담길지 모르니 개별적으로 타임아웃을설정할 수 있는 것을 찾아보니, redis 를 이용한 방법이 있어 적용했다.

또한 session을 적용해서 인증번호를 확인과정을 할때 http 요청으로 서버에 저장된 인증번호값과 비교를 하니, session에 설정된 타임아웃이 계속해서 갱신이 됐다.이게 무슨말이냐면 session 타임아웃으로 1분을 설정하였더라도 클라이언트에서 http요청을 하게되면 세션의 설정된 타임아웃 1분이 다시 1분으로 초기화된다... 그래서 틀린 인증번호를 가지고 계속 요청하면 세션에 저장된 인증번호는 계속 타임아웃이 갱신되는거다.. 만약 사용자가 아무 동작을 안하고 1분이 지나면 그 데이터는 사라지긴 하다만 유저가 어떤 돌발행동을 할지 모르니 redis로 적용!

 

Redis란?

오픈 소스 기반의 인메모리 데이터 저장소다

주로 데이터 캐싱, 세션 관리, 실시간 데이터 처리등에서 사용되며

SQL 기반 데이터베이스와 다르게 key-value 구조로 데이터를 저장한다

또한 데이터를 디스크가 아니라 RAM에 저장하므로 매우 빠른 속도를 제공한다

쉽게 표현하자면 key-value 식으로 사용되는 저장소라고 하면 될 것 같다

 

 

우선 redis의 설치가 필요하다

 

Redis 설치방법

 

 

https://github.com/microsoftarchive/redis/releases

 

Releases · microsoftarchive/redis

Redis is an in-memory database that persists on disk. The data model is key-value, but many different kind of values are supported: Strings, Lists, Sets, Sorted Sets, Hashes - microsoftarchive/redis

github.com

 

위 링크로 접속하여 

 

 

.msi 파일을 다운받아준 뒤 설치해준다

 

 

Spring

 

pom.xml

<!-- Spring Boot Starter Data Redis -->

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-redis</artifactId>

</dependency>

 

redis 의존성을 추가해준다

 

 

application.properties

# Redis 기본 설정

spring.redis.host=localhost

spring.redis.port=6379

 

spring.redis.host=localhost

이 속성은 Redis 서버가 어디에 위치하는지 지정한다. 기본적으로 Redis는 **localhost (127.0.0.1)**에서 실행되어 localhost는 로컬 서버에서 Redis를 사용한다는 의미이다

spring.redis.port=6379

설치했을 당시에 적용한 포트번호를 적용해준다 

 

 

인증번호 생성 및 redis 저장 기능 class

@Service

@RequiredArgsConstructor

public class ImSignUpEmailService {

 

private final JavaMailSender javaMailSender;

private final StringRedisTemplate stringRedisTemplate;

 

//이메일 발송

@Async

public void sendEmail(String userEmail) {

 

SimpleMailMessage message = new SimpleMailMessage();

message.setTo(userEmail);

message.setSubject("Im 회원가입 인증번호");

message.setText("인증번호 : "+verification(userEmail));

javaMailSender.send(message);

 

}

 

//인증번호 만들기 + 레디스에 1분유효로 값 저장

public String verification(String userEmail) {

String passSet = "ABCDEFGHIJKLMNOPQRSUVWXYZ0123456789";

Random random = new Random();

String pass="";

for (int i = 0; i < 8; i++) {

int randomIndex = random.nextInt(passSet.length());

pass+=passSet.charAt(randomIndex);

}

// 레디스에 현재 이메일로 저장된 값이 있으면 삭제 _ 인증버튼 중복으로 누를때를 예방하기위함

stringRedisTemplate.delete(userEmail);// 기존 인증번호 삭제

 

// 레디스에 현재 이메일 키값으로 인증번호 저장 _ 타임은 1분

stringRedisTemplate.opsForValue().set(userEmail, pass, 1, TimeUnit.MINUTES);

 

return pass;

}

 

}

 

private final StringRedisTemplate stringRedisTemplate;

spring에서 제공하는 클래스다 redis에 데이터 저장하고나 조회할때 사용한다

 

원래는 RedisTemplate<String, Object> redisTemplate 가 있지만(객체,리스트, 해시 등 다양하게 다룸)

string 값만 다룰 예정이라 StringRedisTemplate를 사용했다

 

 

sendEmail()

위 메소드 내에 .setText(내용) 부분에 입력되는 verification(userEmail)

메소드가 인증번호 생성과 동시에 redis에 저장이 되는 방식이다

 

인증번호 생성은 알파벳과 숫자의 랜덤 6개 조합으로 보내게 만들었다

그러면 인증번호 생성 및 저장 메소드에 대해 알아보자

 

 

verification(String userEmail)

위 메소드가 인증번호 생성 및 redis에 저장하는 방식인데,

 userEmail을 받은 이유가 2가지가 있다 

 

현재 회원가입 하는 유저의 인증번호를 개별로 확인 할 수 있게 만들엇다.

(만약 동시에 두명의 유저가 회원가입을 할 때 같은 이름의 키값으로  데이터가 저장되면 안된다는 생각에..)

또한 회원가입 시 등록하려는 이메일을 키값으로 사용했다

 

// 레디스에 현재 이메일로 저장된 값이 있으면 삭제 _ 인증버튼 중복으로 누를때를 예방하기위함

stringRedisTemplate.delete(userEmail);// 기존 인증번호 삭제

delete > 해당(userEmail) key값이 저장되어있다면 삭제

 

우선 나는 해당 이메일로 저장된 키값을 삭제하는 과정을 만들었다

(왜냐 회원가입 시 사용자가 인증번호 받는 버튼을 계속해서 누를수도 있다는 생각에.. 그렇게되면 새로운 인증번호를 다시 저장해줘야하니까)

 

 

 

 

stringRedisTemplate.opsForValue().set(userEmail, pass, 1, TimeUnit.MINUTES);

opsForValue() : redis의 값(value)에 관련된 작업을 수행할 수 있는 기능제공

 

set() : redis에 데이터를 저장

 

userEmail , pass , 1 , TimeUnit.MINUTES 

 

userEmail : key값으로 등록된다

>유저가 입력한 userEmail값으로 해당 데이터의 이름을 정해준다

 

pass : value값으로 등록된다

>만들어진 인증번호가 value값으로 

 

1 : 유효기간을 설정해준거다

TimeUnit.MINUTES : 단위를 설정한다

>여기서는 minutes 분으로 설정한거다

즉 두개 합쳐져서 1분의 유효기간을 설정한거고

1분이 지나면 해당 데이터는 삭제된다

 

이게 포인트인데 해당 데이터가 1분이 설정된거니 타임아웃으로 다양하게 지정할 수 있는 장점이 있다

 

 

 

구현 결과


redis 설정으로 인해 타임아웃 기능을 적용시킬 수 있엇다

 

 

 

 

 

 

 

 

 

+ Recent posts