이번 글에서는 로그인의 흐름에 대해 기록해보려고한다.
기록하는 이유는 아직 내가 자연스럽게 구조를 떠올리지 못하는 것 같기 때문이다.
흐름을 따라가면서 한번 살펴보자.
처음에 유저가 보는 페이지는 LoginPage
이다.
이 페이지에서 유저는 아이디와 비밀번호를 입력하고 로그인을 진행한다.
handleSubmit
함수는 로그인 버튼을 누르면 실행되는 함수이다.
loginUser
액션 함수를 디스패치한다.loginUser
액션함수는 POST
방식으로 /api/users/login
으로 로그인정보를 담아서 요청을 보낸다.
/api/users/login
1번에서 보낸 로그인 아이디와 비밀번호가 req
객체에 저장되어온다.
req.body
에 그 정보가 담겨있고 꺼내서 사용할 수 있다.
그 다음 email
(아이디) 정보로 DB에서 User를 찾는다.
유저가 있으면 매치하는 user
객체가 생긴다.
만약 DB에 찾는 유저가 없으면 loginSuccess: false
, message
를 반환한다.
해당하는 유저가 있으면 입력한 비밀번호와 DB에 저장돼있는 비밀번호를 비교한다.
비밀번호가 일치하지않으면 로그인이 실패한다.
비밀번호까지 일치한다면, 토큰을 생성한다.
User 스키마에 선언되어있는 함수이다.
token
을 생성하고, 생성된 토큰을 user
스키마의 token
필드에 넣어준다.
그 다음 데이터베이스 상태를 저장한다.
user.save
안에서 cb 라는것을 확인할 수 있는데, user.generateToken
함수를 호출할때 넣어준 콜백 함수이다.
(err, user) => {
if (err) return res.status(400).send(err);
res
.cookie("x_auth", user.token)
.status(200)
.json({ loginSuccess: true, userId: user._id });
}
유저의 토큰 필드값(user.token
) 을 x_auth
라는 이름의 쿠키에 저장한다.
그 후 상태코드 200과 json 객체를 응답한다.
/api/users/login
에서의 일은 여기서 끝이다.
하지만 쿠키를 저장했으면 인증을 해야하지 않겠는가?
그러면 인증은 언제에 해야할까?
우선 인증에 대해 살펴보기전에 이 프로젝트의 Routes부터 봐야할 것 같다.
이런식으로 구성되어있다.
element쪽을 보면 AuthHOC
라는 컴포넌트가 보인다.
이 컴포넌트는 하이어 오더 컴포넌트 (Higher-Order Component) 라고하는 컴포넌트인데, 다음과 같은 역할을 한다고 한다.
컴포넌트 로직을 재사용하기 위해 사용되고 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수입니다.
즉, 컴포넌트를 인자로 받거나 반환하는 함수입니다.
AuthHOC
컴포넌트를 살펴보자.
이런식의 구조로 되어있다.
그리고 컴포넌트들이 마운트 될 때, auth()
액션 함수를 dispatch
하는 것을 볼 수 있다.
auth
액션함수 👇
auth
미들웨어 👇
/api/users/auth
👇
auth
액션 함수를 dispatch
하면 /api/users/auth
로 GET 요청을 보낸다.
그런데 api/users/auth
는 미들웨어를 한번 거치고 (req, res) => ...
이 부분을 실행한다.
auth
미들웨어는 현재 저장되어있는 쿠키 값을 토대로 DB에 등록된 유저를 찾는다.
로그인이 안돼있으면 현재 브라우저에 저장되어 있는 쿠키값이랑 DB에 일치하는 쿠키값이 없을것이다.
(로그아웃 할 때, User 스키마에 저장된 token 값을 지우고 업데이트 함)
성공적으로 유저를 찾으면 req.token
에 현재 브라우저에 있는 쿠키값을 저장하고
req.user
에는 유저 정보 (이메일, 이름, 주소 등등) 을 저장한다.
그 다음 /api/users/auth
에서 현재 유저 정보를 클라이언트에 응답으로 보내준다.
그리고 페이지를 이동할 때 마다 auth
디스패치를 수행한다...!
로그인의 흐름을 쭉 살펴봤다..
오랜만에 Express와 mongoDB 관련 코드를 봐서 그런지 복잡하다!
글로 적으면서 어떤 흐름인지 대충은 느낄 수 있었으나, 여러번 볼 필요성을 느꼈다.
그리고 쿠키, 세션, 인증방식에 대해서도 공부를 해야겠다!
이런 이론적인 부분이 아직 숙지가 안되서 그런지 더 복잡하게 느껴진 것 같다. 🥲