현재 회사에서 만들고 있는 서비스에서 이메일을 통한 인증 방식을 사용하는 부분이 두 군데 있다.
회원가입 시 사용한 이메일을 인증하는 부분과 비밀번호를 찾을 때 전송된 메일을 통해서 들어온 경우에만 비밀번호 재설정을 할 수 있게 하는 부분이다.
지금은 단순히 이메일 내 버튼에 이동시킬 페이지 주소를 넣어놓고 클릭 시 해당 페이지로 이동하도록 되어있다.
회원의 verify 정보도 업데이트 해야하고, 비밀번호 찾기에서는 회원 정보도 있어야 하는데..
이메일을 통한 인증을 처음 구현하다보니 잘 모르긴 몰라도 이렇게만 해서는 인증이 되는건 아닌 것 같아서 (당연)
'어떻게 구현해야하는걸까?' 를 찾아보고 알게 된 내용을 정리해보려고 한다.
잘 모르는 부분과 이해가 안갔던 부분을 처음부터 좀 되짚어봤다.
일단 인증 방식. 보통 어떤 식으로 이메일 인증을 구현하는지를 먼저 찾아봤는데 크게 두 가지 방식이 있는 것 같다.
1. 메일 내용에 인증코드를 적어주고, 해당 인증코드로 인증하도록 하는 방식
2. 메일에 링크만 전달하여 해당 링크로 인증하는 방식
1번의 경우 랜덤값을 생성한 후 DB에 저장하고 메일에도 전송을 한 다음, 특정 페이지로 이동시켰을 때 해당 랜덤값을 입력해서 일치하는지 확인하여 인증하는 방식이고
2번의 경우는 메일에 있는 링크를 통해 접속했을 때 인증이 되는 방식이다.
우리의 서비스 기획에는 인증코드 방식이 아니라 메일에 있는 버튼 클릭하면 인증이 되어 다음 플로우를 진행하는 방식으로 되어있다.
비밀번호 찾기를 하게 되면 링크를 통해 이동한 페이지에서 어떤 사용자의 비밀번호를 바꾸는 것인지, 사용자에 대한 정보를 알 수 있어야 한다. 버튼에 연결한 주소의 쿼리스트링으로 사용자의 이메일을 그대로 넘겨도 되겠지만 이게 보안상 괜찮은 것인지에 대한 걱정이 있었다.
이메일을 그대로 넘기게 되면 어떤 사람의 이메일을 알았을 때, 비밀번호 변경 페이지의 주소와 합쳐서 url만 입력하면 누구든지 비밀번호 변경 페이지에 들어갈 수 있기 때문에 좋지 않을 것 같았다.
찾아보니 토큰
을 만들어 쿼리스트링으로 넘긴 후에 사용하는 것 같아서, 이 단계까지 찾아봤을 때에는 클라이언트에서 JWT
를 발급받은 후 메일에 넣어주도록 하게끔 만들 생각을 했다.
이 부분이 제일 이해가 안되서 계속 찾아봤던 부분인 것 같다.
회원 가입 이후의 이메일 인증 과정에서는 메일의 버튼을 클릭했을 때 이 사용자는 인증이 되어 로그인을 할 수 있다!
를 판단할 수 있도록 사용자의 인증 상태에 대한 값을 변경시켜줘야한다.
그러면 생각을 해봤을 때 백엔드의 API를 호출해서 사용자 상태를 바꿔주면 될 것 같은데 버튼 클릭했을 때 페이지 자체는 로그인 페이지로 이동이 되어야 한다.
그래서 이메일 템플릿에서 스크립트도 사용할 수 있나 했는데 그건 안된다고 한다.
그러면 도대체 어떻게 해야하는거지????
계속 찾아봐도 그냥 토큰 만들어서 인증하는 것만 나오고 내가 궁금한건 도대체 어떻게 원하는 페이지로 이동시키는건데!!
였다.
검색어를 좀 바꿔서 이메일 인증 후에 리다이렉트
로 검색을 해서 찾아보다가 마침내 원하는 답을 찾았다!!
찾아낸 해결 방법은 response.redirect
를 사용하는 것이다.
이 블로그의 인증 확인 부분에서 response.sendRedirect
를 하는 부분이 있는데,
우리는 nodejs를 사용하고 있기 때문에 좀 다를거라 생각했고 찾아보니 sendRedirect가 아니라 그냥 redirect를 사용하면 되는 것 같았다. 근데 이제 redirect 뿐만 아니라 forward라는 것도 같이 나와서 좀 찾아봤다.
그리고 지금 이 글을 쓰는 시점에서 (계속 찾아보면서 쓰고 있음)
NestJS에서 애초에 Controller 쪽에 @Redirect
를 제공하고 있다...ㅎㅎ..
역시 공식문서 정말 중요하다!ㅎㅎ
쓰다보니 인증 과정 구현하는걸 시리즈로 써도 좋을 것 같아서 이번 글은 내가 뭘 모르고 헷갈렸던건지, 어떻게 찾아봤는지, 결론은 어떻게 냈는지에 대해서만 쓰려고 한다.
그래서 결론은!
회원가입 인증 메일
버튼에는 백엔드 API의 endpoint를 연결해두고 버튼을 클릭해 API가 호출되면 사용자의 인증 상태 값 업데이트하고 원하는 페이지로 redirect 시키기
비밀번호 찾기
버튼에 연결시킬 url의 쿼리스트링으로 사용자 정보를 담은 JWT가 설정되도록 해서 이메일을 보내고, 해당 페이지에서 JWT 값으로 사용자 정보를 가져와 사용할 수 있도록 하기
이렇게 생각했다.
근데 회원가입 인증 메일, 비밀번호 찾기 둘다 30분 제한 시간 내에 실행되었을 때만 할 예정이라서 JWT에는 expiresIn을 설정하면 되지만 회원가입 메일은 어떻게 할지 좀 더 생각을 해봐야할 것 같다.
이것도 마찬가지로 메일 보낼 때 expiresIn 설정되어 있는 JWT를 보내고 받아서 처리할지..
이렇게 하면 될 것 같긴 함..
TO BE CONTINUE...