즐코

세션 (ft.쿠키) / 세션 기반 로그인 구현 본문

NodeJS

세션 (ft.쿠키) / 세션 기반 로그인 구현

YJLEE_KR 2022. 2. 9. 15:40

1/ 세션

1. 세션이란? 

2. 쿠키없이 세션으로만 가능?

3. 세션은 어떻게 사용하나 ?

2/ 세션 기반 로그인 기능 구현해보기

 

1/ 세션

 

1. 세션이란? 

 

어제 배웠던 쿠키는 사용자 데이터(쿠키내용)의 저장을 사용자 측 브라우저가 해주기 때문에,

다른 누군가가 내가 로그인했던 컴퓨터의 브라우저를 파보면 쿠키가 쉽게 노출되므로, 보안에 취약하다.

 

이런 점을 보완하기 위해서, 보안을 요하는 데이터는 서버가 저장해주는 것이 세션이다.

 

쿠키와 세션
: http통신의 불편한(?) 특성 (요청-응답이 한번왔다갔다하면 남이 되는 사이)을 보완하기 위해서 만들어짐 
한 사이트 내에서 서버가 각 특정 사용자를 인지해서 그 인지한 상태를 유지하기 위한 인식표, 인증서 같은 개념 

쿠키 : 데이터 보관의 주체 = 개인 / 클라이언트 쪽 브라우저
세션 : 데이터 보관의 주체 = 서버

 

 

 

2. 그럼, 쿠키는 아예 안쓰고 세션으로만 통신을 하면 안되나?

 

 

- 사용자수 : 무한대, 예측불가함

- 서버쪽 컴퓨터(자원) : 개수나 성능에 있어서 한계가 있음

 

=> 서버쪽만 데이터를 저장하고 이 세션으로만 상태유지를 한다면,

사용자 수가 많아질수록 서버쪽 자원은 한정적이니까 서버의 부담이 높아질거다. 

사용자가 특정 시간대에 많아지면, 과부하가 걸릴 수도 있다.

 

서버 쪽의 한정된 자원을 효율적으로 쓰고 사용자의 편리함(웹사이트의 속도)을 위해 쿠키와 세션을 적절하게 병행해서 씀

 

 

 

 3. 세션은 어떻게 사용하나 ?

 

그래서 서버가 쿠키를 주긴 주는데, 알 수 없는 긴 임시 key와 사용자 정보를 매칭시켜서 서버쪽에 데이터를 보관(세션) 하고,

그 임시key만 쿠키로서 클라이언트 쪽 브라우저에게 던져주는 것

이 비밀키처럼 만들어진 쿠키를 가지고 요청을 해야만 서버가 사용자를 판단해서 응답해줄 수 있다. 

그래서, 브라우저를 끄기 전까지는 상태 유지가 가능하다.

 

 

위 과정을 구현해보자..


2/ 세션 기반 로그인 기능 구현해보기

 

1. 임의로 서버쪽 DB 만들어주고 데이터 끌어오기

 

이때, 나는 처음에 CRUD 게시판 만들땐 module.exports = userData 이런식으로 객체자체를 보내줬는데,

교수님은 이걸 객체 안에 담아서 보내서 객체의 키값으로 데이터를 끌어왔다.

나중에 업데이트되는 데이터를 추가하기가 좋다고한다.

 

 

모듈을 가져올 땐, 아래와 같이 그냥 통으로 가져오면

우리가 원하는 userData 배열은 userData라는 key값의 value로 객체에 들어가진채로 출력된다.

따라서, {userData} = require('./userData.js') 이렇게 {key값} 형태로 객체 안의 데이터를 가져오자.
<이런게 비구조화 할당>

 

<이렇게 수정함>


2. 기본적인 메인 페이지 router와 get 요청에 따른 로그인 페이지 router 구성 

 

저번에 했으니 설명은 생략,

참고로 로그인 페이지는 nunjucks가 끌어올 html 파일을 저장하는 디렉토리명(views) 안에

user라는 디렉토리를 하나 더 만들어서 login.html 을 저장함, 그래서 render할 html 경로를 './user/login' 로 한 것

 

 


 

3. post 요청에 대한 로그인 페이지 router

 

어제 했던 것처럼 사용자입력 form data와 내 서버 userData와 일치하는지 확인하는 게 포인트 

 

 

#1. post로 들어온 form 데이터 파싱해오기

 

 

 

#2. 근데 이번에는, 로그인 성공과 실패를 가리는 건 함수로 따로 빼서 만들어보자. (userData.js 파일로 뺐음)

 

우리가 가진 userid,userpw와 사용자가 입력한 id,pw가 일치하는지 확인하고

일치하면, true return

아니면, false return해주는 구조로 짠다.

 

<userData.js> 

 

#3. 당연히, server.js 파일에도 require를 써서 끌어오기

 

이때도 객체 비구조화할당이 쓰인다.

 

<server.js>

 

#4. loginFlag라는 변수에 함수를 담아주고, loginFlag 가 true일때 즉, 로그인이 성공했을 시 임의의 쿠키값을 줘보자.

 

이런 방식으로 서버가 브라우저에게 쿠키값을 주는 건 아니지만, 우린 그냥 아무의미없는 nonce값을 주기 위해서

Math.random() 함수를 활용했다 + 소수점 절사하려고 ParseInt 사용

 

 

맞는 id/pw 입력하고 로그인 버튼을 누를 때마다 아래와 같이 임의의 값이 출력된다.

 

 

우리는 이 랜덤한 nonce값을 쿠키값으로 써야하고, 이 쿠키값이 사용자 데이터를 확인할 열쇠의 역할을 해줘야한다.

 

이걸 기억해두고, 다시 돌아가서 사용자가 로그인할 때, 해당 id, pw가 맞을 때 그에 해당하는 값을 뽑아내자. 

 

 

#5. 서버 DB에 저장된 사용자 정보를 useritem이란 변수로 선언하고,  사용자가 입력한 ID === DB속 데이터 ID 일 때,

     정보를 꺼내서 useritem에 담자. 

 

배열 속에서 객체를 하나씩 꺼내서 useritem의 빈 객체에다가 id/pw/name을 담아준다. 

 

 

맞는 id/pw로 로그인할 때마다, 아래와 같이 아이템들이 객체에 담겨져서 나온다.

 

 

 

#6. 우리는 이제 위에서 뽑아낸 privateKey(쿠키값)와 useritem(사용자데이터)를 합쳐야한다.

 

session이라는 객체를 서버인 우리가 저장하고, (session = 쿠키값 + 사용자정보를 다 포함한 객체)
이 무작위 쿠키텍스트만 브라우저에게 쏴줘야한다! (브라우저에게 열쇠를 쥐어주는 것)

 

우선 빈객체인 session을 선언하자. 

 

 

session이라는 빈객체안에 privateKey라는 key값을 주고 + 그안에 useritem을 key의 value값으로 주자.

즉, 쿠키값이 key가 되고, 사용자데이터가 그 쿠키의 속성값인 구조이다. 

 

 

로그인 할 때마다 서로 다른 privateKey(쿠키)와 해당 사용자 정보가 객체 담겨져서 나온다.

 

 

쿠키 : text 형태 (사용자인 브라우저에게 전달할 소통의 열쇠)
세션 : 객체 형태 (서버가 가질 데이터 잠금 상자)

 

 

#7. 드디어 브라우저에게 이 만든 쿠키를 줘야한다. 어떻게? 응답헤더로 준다. (setHeader 사용!)

 

쿠키name은 아무렇게나 지어도되지만, connect.id를 쿠키name으로 많이 쓴다고 하니 이렇게 넣자.

path는 어디영역에서 사용할 쿠키인지 정하는 것,
사용자(브라우저)는 이 쿠키를 자신의 로그인 유지를 위해 전 페이지에서 다 쓸테니까 path='/'로 설정한 것

 

 

맞는 아이디/비번으로 로그인해보면, 

서버쪽엔 아이디마다 쿠키와 사용자정보가 매칭되어서 저장되고

 

 

브라우저쪽엔 쿠키값(privateKey)만 저장된다. 

 

 

 

#8. login실패시도 짜보자

 

이건 자세하게 해석하자면,
서버가 브라우저에게 너 이걸로 다시(re) 나한테 요청해 라고 지시(direct)하는거다. (redirect)
그러면 브라우저가 오케이~~ 하고 저 url로 다시 서버에게 요청을 주는 것, 이때 쿼리문으로 msg를 넘겨주는거다.

(눈에는 안보이지만, 따지고보면 요청->응답이 2번 일어난것)

 

 

get 요청으로 받은 msg 활용을 위해 로그인 페이지 router에 추가를 좀 더 해보자.

get 요청으로 들어온 url 파싱해서 msg 변수로 nunjucks에게 던져주기

 

 

받은 msg 변수로 넌적스 조건문 쓰기 

msg가 있으면 경고창 띄워줘라

 

 

잘못된 아이디/패스워드 입력하면 아래와 같이 경고창이 뜬다.

 

 

 

이건 로그인 기능만 구현한 건데도 코드가 사알짝 복잡하다. 

여기에 게시판기능까지 넣으면 더 길어질 것이다. 

 

그래서 각 코드를 라우터끼리 미들웨어끼리 (라우터 안에서 두번째 인자로 들어갔던 콜백함수부분) 나눈다고 한다.

그건 내일 마저 정리해야겠다

Comments