개발/프로젝트

[세션 / 토큰 로그인 프로젝트] 진행 전 공부 과정.. express에서 지원하는 쿠키? 세션 쿠키? 쿠키와 세션 구분하기

prpn97 2023. 7. 7. 22:30

이전에 세션 / 토큰 로그인의 과정을 설명했기에 세션 로그인 과정을 간단하게만 설명하고,

본론으로 들어가고자 한다. 

 

세션 로그인에 대해

세션은 비밀번호처럼 인증 정보를 저장하지 않는다. 그 대신 sessionID라는 식별자를 저장한다. 

쿠키에 sessionID가 존재하지 않을 경우, 서버에 요청하여 sessionID를 받아 쿠키에 보관한다.

 

이후 클라이언트가 서버에 요청하면 서버는 sessionID를 key로 가지고 있는 value의 값을 조회,

로그인 여부 혹은 중요 정보를 확인한다.

 

 

즉, id와 pw로 로그인했을 때 쿠키에 sessionID가 없으면 서버에서 sessionID를 생성,

쿠키에 담아서 보낸다. 이제 쿠키에는 sessionID가 담긴 상태이기 때문에

로그인한 후 로그인한 상태를 유지하기 위해서는 sessionID를 서버에서 확인하고 유지해준다.

 

 

그런데 머릿속에 쿠키에 관해서 정리가 잘된 것 같은데, 세션 로그인을 구현하면서 꽤 애먹었다.

쿠키랑 세션쿠키는 다른가? app.use로 세션에서 쿠키를 설정하는데 req.cookie는 무엇인가?

 

쿠키 만드는 방법 / 쿠키의 구분

일단 결과값을 먼저 살펴보자.

res.cookie('sessionID', req.sessionID, { expires: expires, httpOnly: true });

첫번째 매개변수로 이름, 두번째로는 쿠키에 넣을 정보, 세번째는 설정이다. 

위에서 언급한 과정과 같이 쿠키에 sessionID를 담는 과정이다.

 

설정에는 express에서 제공하는 expires, maxAge, signed 등 여러 기능이 있다.

 

그 중, expires와 maxAge는 둘 다 쿠키의 유효기간을 지정해주는 것인데,

expires는 쿠키의 만료시간을 절대적으로 지정,

maxAge는 현재시간을 기준으로 쿠키가 유지될 시간을 상대적으로 지정한다.

 

그런데 여기서 구분해야 하는 것은, 세션 쿠키는 웹브라우저가 종료될 때 제거된다. 

그렇다면 만료기간이 의미가 없지 않나? 

만료기간을 지정하는 이유는, 브라우저의 종료여부와 상관없이 쿠키를 유지해야 하는 경우인데,

이는 session cookie가 아니라 permanent 쿠키이다.

 

그래서 expires 혹은 maxAge를 지정해주게 되면 세팅한 시간을 확인 할 수 있지만,

지정하지 않았을 때는 db에는 각 값이 null로 확인되지만

개발자도구에서 확인하면 Session이라고 구분하고 있다.

 

req.cookies를 확인해보면 다음과 같다.

sessionID는 res.cookie로 설정한 대로 담겨있다. 

connect.sid와 my session cookie는 무슨 차이가 있는 것일까?

확인하기 전에 잠시 살펴보면, my session cookie 앞부분에 sessionID가 그대로 박혀있다.

 

connect.sid는 express-session을 사용하여 쿠키를 설정했을 때 기본 설정된 쿠키 이름이다.

그리고 app.use에서 session name을 my session cookie로 바꿨고,

쿠키가 남아있는 상태로 이름을 변경했기 때문에 req.cookies를 확인해보면

res.cookie로 만든 쿠키와 app.use({session name:~ , cookie:~ ... })으로 만든 쿠키가

같이 확인되는 것이다.

 

 

다음 스크린샷은 콘솔로 req를 찍었을 때 세션과 관련된 값들의 예시다.

이 정보들은 app.use로 만든 세션과 관련된 정보들이다. 

아까 req.cookies로 찍었던 값과는 왜 다른 것일까?

req.cookies는 res.cookie로 내가 만든 값들을 보내준 것이다.

단지 쿠키에 만들어진 sessionID를 보냈을 뿐이다.

여기서 sessionID는 app.use로 맨 앞단에서 전역으로 설정해주었기 때문에 계속해서 바뀐다.

그러면 cookie? data? 는 무엇인가. cookie는 app.use로 쿠키를 설정한 값이다. 

 

그리고 data는 내가 만든 값인데, 이렇게 만들어볼 수 있다. 

      req.session.data = {
        authenticateUser: true,
        user: username,
        createdAt: koreanNow.toISOString().slice(0, 19).replace('T', ' '),
        expires: expires.toISOString().slice(0, 19).replace('T', ' '),
      };

username, koreanNow, expires는 사용자id, 한국기준시간, 한국기준 민료시간을 담았는데

중요치 않으니 설명은 생략하겠다. 중요한건 이 설정 그대로 세션에도 담을 수 있다는 것이다.

 

 

세션과 쿠키의 이해관계

여기까지 장황하게 여러가지 확인하면서 깨달은 것이 있다.

세션과 쿠키가 상관없다고 보긴 힘들지만, 쿠키는 그저 세션을 확인하는 수단인 것이다. 

그래서 express에서 제공하는 여러가지 기능 중에서 세션과 쿠키가 나뉘어져 있는데,

그렇기 때문에 express-session과 cookie는 별개로 설정하는 것이다.

 

그래서 req.cookies를 확인해보면 세션으로 만든 쿠키와 별도로 만든 쿠키가 같이 확인된다. 

사실 구분할 것도 없이 세션에서도 쿠키를 만든 것이기 때문에 같은 쿠키인 것이다.

 

이걸 모른 채로 왜 res.cookie로 설정을 했는데 session에서 cookie는 뭐고

설정한게 여기서는 바뀌고 저기서는 안바뀌는가 하루종일 테스트한 것 같다. 

 

근원으로 돌아가면, 세션로그인은 세션id를 쿠키에 넣고 쿠키가 오고가는 것이다.

그리고 그 세션id는 서버에 일시적으로 저장되어 있고, id / pw대신 인증하기 때문에

사용자의 입장에서는 매번 로그인할 필요 없이 인증과정이 뒤에서 오고가는 것이다.

 

 

지워도 남아 있는 sessionID..?

추가로, req.clearCookie로 로그아웃하면 쿠키를 지울 수 있는데,

위 스샷처럼 req.sessionID가 그대로 남아있었다.

clearCookie로 지우고 나면 개발자도구에서 확인할 수 없기도 하고,

별도로 남아있던 쿠키도 직접 다 삭제하고, req.session.destroy()로 세션도 지웠다.

그런데 왜 req.sessionID가 남아있는 것일까? 

 

먼저, 쿠키를 지우는 것은 상관이 없다. 쿠키에 세션을 담았을 뿐 세션id가 사라질 이유가 없다.

req.session.destroy()를 했을 때, 전 후로 req.session을 확인해보면

destroy 전에는 req.session이 확인되고, 후에는 undefined가 확인되는걸 보면

destroy가 분명 작동하고 있고, 지워진다는 뜻이다. 

 

 

그런데 destroy해도 req.sessionID가 확인되는 이유는 이렇다.

지워지지만, 전역으로 session을 생성하기 때문에 새로 생성된 req.sessionID가 확인된다.

그렇기 때문에 지워진 시점에서는 req.session을 확인할 수 없지만,

req.sessionID을 확인하는 로직 이전에 session이 만들어졌기 때문에

새로운 sessionID를 확인할 수 있는 것이다.

 

코멘트

세션로그인을 구현해야 하니 express의 세션을 사용했고, 

세션id를 쿠키에 담는다고 하니 express의 쿠키를 사용했다.

 

express에서 세션에 cookie 기능이 있기 때문에 그대로 사용하면 되는데

이유도 모른 채 express의 쿠키 기능을 쓰면서 혼동이 있었던 것 같다.

역시 '왜'가 참 중요한 것 같다. 왜 사용하고, 왜 작동하는지 확실히 해야겠다.

 

 

결론적으로 맨 위 스샷을 보면서 세션을 생성하면서 만든 connect.sid에

왜 세션id값이 그대로 들어있었냐고 하면, express에서 친절하게 세션을 만들 때

쿠키 안에 세션id를 담아주고, 그대로 사용하도록 해준 것이다.

지금 생각해보니까 애초에 이름부터 .sid인게 sessionID 인 것 같다...^^

728x90