초보 개발자

join, login, logout handler ( SESSION ★★★) 본문

RECAP - WETUBE

join, login, logout handler ( SESSION ★★★)

taehyeki 2021. 9. 24. 23:15

먼저 join handler를 만들어 보겠다.

여기서 새로운 Model인 User모델을 만들고 bcrypt를 활용해 비밀번호를 해시하여 암호화 시킬 것이다.

getJoin

getJoin을 통하여 /join url로 들어왔을 때 join.pug를 보여주도록 한다.

 

join.pug

form을 만들고 그 안에 id를 뜻하는 iden와 password, email, name 등을 post방식으로 보낼 것이다.

 

postJoin

req.body로 먼저 정보들을 받아온 뒤에 iden, email이 기존의 것과 중복이 되는 지의 여부를 확인하고

중복이 된다면 status(400) (bad request)를 보내준다. 안보내면 아이디와 비밀번호를 저장할 것인지를 브라우저가 물어보는데 이것은 자동적으로 status(200) (OK request)가 보내진 것이기 때문이다.

비밀번호도 두개 다 맞다면 이제 User.create를 이용하여 아이디를 생성해준다. 

 

User

Video model과 마찬가지지만 여기서 다른점은 미들웨어를 사용한다는 점이다.

bcrypt를 사용하여 비밀번호를 해쉬화하여 조작하지 못하도록 하는 것이다.

일방향 함수이므로 입력값으로 출력 값을 알아낼 수 는 있지만 반대로 출력값을 통해서 입력값을 알 수는없다.

 

근데 여기서 궁금한점이.. 솔트의 값을 5로 지정해 두었지만 예를들어

아이디 m1 / 비밀번호 12 --> adkfjaldfkjlak

아이디 m2 / 비밀번호 12 --> nfnjiqf314156

같은 입력값으로 같은 출력값을 내보야 한다고 생각하였지만 위와 같이

다른 해시값이 나와서 한참을 찾아봐도 명쾌한 해답을 찾지 못하였다..

 

근데 신기한점이 login 기능을 구현할 때 두개다 12로 접근할때 true를 나타내었다. 어떻게 그게 가능한걸까..???

 

이번엔 login handler를 만들어 보겠다.

getLogin

login.pug

join.pug와 비슷하다. 로그인에 필요한 ID와 PASSWORD를 받아오자

 

postLogin

받아온 ID와 PASSWORD를 통하여 id가 있는지, 또 있다면 비밀번호가 맞는지를 확인한다.

여기서 비밀번호를 확인하는 방법은 bcrypt를 활용하여 compare을 돌려보면 알 수 있다.

이 부분에 대해서 정확히 알지는 못하지만 대략적으로 우리가 해싱된 출력값을 가지고 있으니 입력값이 같다면 같은 출력값이 나올 것이므로 이를 통해 일치 유무를 확인하는 것 같다.

 

이렇게 둘 다 이상이 없다면

req.session에 정보를 담아둔다. 

엥? 근데 session이 뭐에요??? 이제부터 session에 대해 설명해보겠다.

 

서버는 기억력이 3초인 아니 기억력이 없다고 생각해보자. 따라서 우리가 로그인을 했어도 서버는 기억을 하지 못한다.

바로 연결이 끊기는 stateless상태가 되어버린다. 이러면 로그인하는 의미가 전혀 없어져 버린다. 따라서 우리는 웹브라우저와 서버를 이어주는 끈 같은 역할인 session에 대해 배워보겠다. 

 

세션과 세션id는 브라우저를 기억하는 방법 중 하나이다.

서버에서 세션이라는 것을 만든다. 이 안에는 정보를 담을 수 있다.

이 세션에는 고유한 id가 생성이 된다.

이 id를 브라우저에게 넘겨주고 브라우저는 쿠키속에 담아둔다.

브라우저가 서버로 요청(request)를 보낼 때 마다 쿠키에서 세션id를 가져와 보내준다.

그럼 서버가 그 세션id를 읽고 우리가 누군지, 어떤 브라우저인지를 알 수 있다.  이 쿠키속 세션 id와 일치하는 세션에 접근하여 정보를 알아올 수 있는 것이다. ( 서로 다른 브라우저는 서로 다른 쿠키를 가지고 있다 그래서 서로 다른 세션id를 가지고있다.)

즉 우리가 브라우저에게 줬던 세션id를 서버에 요청을 보낼 때마다 같이 보내고 있는 것이다.
그럼 이제 유저 정보를 기억할 수 있고 유저의 세션에 정보를 추가할 수도있다.

 

이게 바로 서버가 id를 통해서 기억하는 방법이다!!

 

내가 브라우저에서 웹사이트를 방문할 때마다 app,use(session({})) 이 세션 미들웨어가있으면 
express가 알아서!!! 그 브라우저를 위한 세션id를 만들고 브라우저한테 보내준다.
그러면 브라우저가 쿠키에 그 세션 id를 저장하고 express에서도 그 세션을 세션DB에 저장한다.
세션 DB에 있는 id와 쿠키에 있는 id가 같도록 말이다.
그러면 브라우저한테 보내서 쿠키에 저장한 세션id를 브라우저가 localhost:4000의 모든 url에 요청을 보낼 때마다
세션 id를 요청과 함께 보낼것이다. 그러면 백엔드에서 어떤유저가, 어떤 브라우저에서 요청을 보냈는지 알 수 있다.
유저가 로그인하면 그 유저에 대한 정보를 세션에 담을거다
각 유저마다 서로다른 req.session object를 가지고 있다

 

먼저

npm i express-session

express-session을 통해 우리는 간단하게 세션을 조작할 수 있다. route앞에다가 적어줘야 된다는 것을 명심하자.

설정 중 secret은 아무!!에게도 보여주면 안되는 것이라고 한다!! 나중에 바꾸고 숨겨둘텐데 일단은 이렇게 해두자!!

그리고 resave와 saveUni~~~와 같은 설정들도 나중에 다 바꿀 것이다. 일단 이렇게 설정을 해두었다!!

 

일단 세션을 눈으로 보기 위해 다음과 같이 코드를 작성하고 우리가 가지고있는 모~~~든 세션을 보도록 하겠따.

자 !! 이렇게 작성을 하고 localhost를 방문해보겠다, 그럼 세션이 뜰 것이다 ~~!

엥 ?? 세션이 안떴다. 왜 그런 것일까 ?? 

우리가 처음 요청한 request에서는 세션id가 없는 상태일 것이다. ( 애초에 세션을 만들지 않았음 )

request가 요청 된 후에 서버에서 세션을 만들고 그 세션의 id를 request요청을 한 브라우저에 넘겨줬을 것이다.

그럼 브라우저를 한번 확인해볼까?? 

잘 만들어 진 것이 보일 것이다 이제 이 쿠키 속 세션id를 서버에 request를 보낼 때 마다 같이 보내서 세션에 있는 정보를 가져올 수 있는 것이다!!

자 그럼 다시한번 request를 보내고 console창을 확인해보자 이번에는 빈 객체를 반환하지 않을 것이다.

이번에는 생겼다 !! 초록색으로 되어있는 영어숫자가 세션id이다. 브라우저에 있는 id와 잘 보면 같은 것을 알 수 있다.

이 세션은 javascript object이다 따라서 이곳에 정보를 집어 넣을 수도 있다.

이번에 다른 브라우저(크롬 지금은 엣지)에서 접속을 시도해 보겠다.

 

실수로 중간에 서버가 꺼져가지고 세션이 새로만들어져서 기존의 세션id에서 바뀌었다. 이유는 지금 메모리상에 세션을 저장하고있기 때문이다. 이 문제는 나중에 DB에 저장을 해두면 해결될 것이다.

 

아무튼 총 4번의 request가 있었다. 처음 2번의 request는 엣지에서, 다음 2번의 request는 크롬에서 2번씩 request를 보낸 이유는 앞서 설명을 하였다.

자 그럼 이번에는 각 세션에 정보를 담아두어보겠다.

/add url로 들어가면 number의 값을 하나씩 올려서 둘 다 서로 다른 세션에 졉근하고 있다는 것을 보여주고 싶다.

 

Edgy

Chrome

이렇게 확인할 수 있다.

콘솔창과 브라우저의 숫자가 다른 이유는 sessionStore을 출력하는 것이 먼저고 number +1이 추가되는 것이 나중이기때문이다. 

만약 number+1을 추가하는 과정을 sessionStore을 출력하는 과정위에 올려두면 값이 같아지는 것을 확인할 수 있다.

그리고 이걸 확인하는 과정에서 sessionStore.all이 콜백함수인 것을 알 수 있었다.(뒤늦게 실행)

 

자 그럼 아까로 돌아가서 우리는 세션에 로그인 유무와 아이디정보를 집어 넣었던 것을 확인할 수 있다.

postLogin

로그인 한 뒤에 Store에서 보낸 콘솔을 확인해보면

이렇게 잘 담겨져 있는 것을 확인할 수 있다. !!!

 

다른 브라우저에서  접근해보면 다른 세션에는 로그인 정보가 담겨져 있지않다. !!

이렇듯 세션이 우리가 누군지 어떤 브라우저인지 확인할 수 있도록 도와준다.

세션덕분에 서버가 우리를 기억할 수 있게된 것이다. 오우야~

 

마지막으로 우리가 누군지 브라우저에서 나타날 수 있도록 해주고 싶다.

로그인 유무를 통해 다른 nav를 보여주고 싶어 pug에 무작정 req.session.loggedIn을 적어보았는데

 

놀랍지 않게 오류가 뜨는 것을 알 수 있다.

 

pug와 서버가 상호작용을할때 render뒤에 객체를 넘겨줄 수 있지만

res.local라는 곳에다가 값을 넣어두면 pug에서 변수처럼 사용할 수 있게 된다. pug의 기본 기능이다.

 

그럼 미들웨어를 만들고 그 곳에서 res.local에 값을 넣어주도록 하겠다.

 

라우터 이전에 적어주어야 된다 !!! 안 그러면 정보가 입력이 안되겠죠~?

 

pug내에서 변수처럼 활용할 수 있다고 하였다. 자 그럼 이렇게 해보면 되는지 확인해보자!!

 

로그인 전

 

 

로그인 후

 

와우~~~!!!

 

logout기능을 만들어보겠다. 간단!

끝!!!

'RECAP - WETUBE' 카테고리의 다른 글

Github Login - oAuth  (0) 2021.09.27
session의 옵션들(resave, saveUninitialized)과 dotenv  (0) 2021.09.27
delete, search handler  (0) 2021.09.24
watch, edit handler  (0) 2021.09.23
Schema type, 데이터 생성 및 조회 async await  (0) 2021.09.23