티스토리 뷰

JWT 기반 인증을 하는 프로젝트를 진행 중에 있다

시간이 부족하거나 작은 규모의 사이드 프로젝트라면 회원가입 관련 파트는 OAuth2를 이용해 간단히 처리할 수 있다

나는 기존에 했던 프로젝트에서 도메인만 남겨두고 설계부터 전부 바꿔 진행하는 중이기 때문에

재미 반 & 학습 목적 반으로 세세한 부분까지 전부 손을 대보고 있다

 

회원 CRUD는 HATEOAS, Redis 캐시 추상화 때문에 우여곡절이 많았지만 결국 끝냈는데

끝낸 후에 회원 아이디 & 비밀번호 찾기는 어떻게 진행할지 한동안 고민을 했다

지난 프로젝트에서는 구글링을 통해 어찌어찌 thymeleaf, ajax를 이용한 이메일 인증을 했었다

다만 인증 처리 과정도 어설펐고 재사용하기 힘든 코드가 만들어졌다

이번 파트에서 목적은 모던 자바 인 액션을 읽으며 배운

CompletableFuture를 이용해 보는 것과 재사용 가능한 코드를 만드는 것이다

 

우선 아이디 & 비밀번호 찾기 서비스를 담당하는 컴포넌트의 개략적인 모습이다

비동기 실행을 위해 준비한 CustomTaskExecutor인 woomoolTaskExecutor, 메일 발송을 위한 JavaMailSender

비밀번호 찾기 기능을 위해 임시 비밀번호를 제공하기 위한 PasswordEncoder, MemberRepository가 있다

메일 발송과 문자 발송을 위해 필요한 api key, secret 등은 별도의 *.yml 파일을 만들어 주입받는다

 

 

 

아래는 비밀번호 찾기를 담당하는 메서드다

비밀번호를 찾는 클라이언트는 자신의 아이디는 알고 있으니 email을 요청에 담아 서버로 보낸다

서버에서는 이메일이 존재하는 이메일인지 확인 후 없으면 예외를 터트린다

 

임시 비밀번호를 위해서는 SecureRandom 클래스를 사용했다

Math.random() 은 예측 가능한 난수를 사용하기 때문에 실질적으로 난수가 아니라고 하여 조금 더 찾아봤는데

Random 클래스보다 더 안전한 SecureRandom을 사용해봤다

JPA의 변경 감지 덕분에 Member Entity에서 비밀번호를 변경해주기만 하면 트랜잭션이 끝나는 시점에 커밋된다

Entity <-> DTO 간 매핑을 담당해주는 MapStruct를 사용하고 있어 모든 Entity에 getter, setter를 다 열어놨는데

비즈니스 로직에서 Entity에 set을 박아버리는 코드를 지양하기 위해

일부러 changePassword()라는 메서드를 만들어 사용했다

 

message를 보내는 방식은 간단하다

SimpleMailMessage 인스턴스를 생성한 후에 setTo로 수신자를 지정,

setFrom 발신자 지정, setSubject 제목, setText 본문 지정 보내기만 하고 반환받을 필요는 없으니 runAsync를 사용했다

대신 메일 발송 과정 중에 에러가 발생할 수 있으니 에러 처리가 필요하여 현재는 exceptionally()를 추가했다

재사용 가능한 코드를 만들기 위해서는 메일 발송하는 부분을 따로 떼어낼 필요가 있다

SimpleMailMessage 부분부터 메일 발송하는 부분까지 메서드 추출하고 

회원 가입 시 이메일 인증에도 같은 로직을 적용할 예정이다

 

 

 

아이디 찾기의 경우에는 임시 아이디를 발급할 필요는 없으니 트랜잭션에 readOnly = true 옵션을 주어 진행했다

문자 발송은 cool sms를 연동했다 개발 문서에 워낙 잘 나와있고 cool-sms 사이트에서 Java example을 찾아보면 된다 

https://docs.coolsms.co.kr

 

Documents for COOLSMS Developers - 쿨에스엠에스

2008년을 시작으로 12년간의 서비스 개발 및 운영 경험을 담은 메시지 발송 API에 대한 문서입니다.

docs.coolsms.co.kr

 

 

단점으로는 가입 시 300포인트를 주고 이후에는 문자 건당 20원을 결제해야 한다

나는 테스트 용도로 연동하고 사용해보는 게 목적이라 그냥 진행했다

실제로 프로젝트를 배포하고 사용자에게 공개하면 참 좋겠지만 판매 / 펀딩 도메인이기 때문에 실현되긴 힘들 것 같다

배포하더라도 문자 발송의 엔드 포인트는 막아둘 예정이다 필요할 때만 포인트를 충전하고 시연해볼 생각이다

this::checkBalance 메서드 참조는 문자 발송 가능한 잔액을 확인하는 메서드로 맨 아래에 첨부했다

잔액이 20원 미만이라면 예외를 던지도록 했다

checkBalance 메서드는 잔액 확인 후 반환하도록 만들었기 때문에 여기서는 supplyAsync를 사용한 후에

그 값을 받아서 문자 발송을 진행하므로 thenAccept로 이어줬다

 

CompletableFuture를 사용해보는 게 목적이라 best-practice로 만든 건지는 모르겠다

꽤나 많은 시간을 쏟는 프로젝트라 계속해서 개선해나갈 예정이고 나은 방법을 찾게 된다면 리팩터링을 진행할 것이다

문자 발송 과정에 발생하는 CoolsmsException은 checked-exception이라 보기 싫지만 try-catch로 묶어줄 수밖에 없다

 

 

 

마지막 cool-sms에 잔액 확인을 요청하는 메서드다

cool-sms를 사용하기 위해서는 Java SDK를 다운 받아야 하는데 maven, gradle에 의존성을 추가해주면 된다

Message 클래스는 cool-sms의 클래스이고 api-key, api-secret을 통해 만들어주면 cool-sms에 잔액 확인 요청이 간다

balance는 { "cash" : "충전된 금액", "point" : "처음 준 300포인트" } 형식으로 넘어오기 때문에 get("point")로 꺼내고 

point 값 만을 넘기기 위해 문자열로 변환 후 다시 int 형으로 변환해주어야 한다

만약 cool sms에 충전하여 사용한다면 잔액을 get("cash")로 뽑아내야 할 것이다

예외가 터질 시에는 0을 넘겨 문자 발송이 이루어지지 않도록 한다

댓글
링크
글 보관함
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Total
Today
Yesterday