Node.js

Node.js + MongoDB 로그인확인후 마이페이지(passport.deserializeUser)

svdjcuwg4638 2023. 5. 22. 11:27

전글

https://daehyuntsory.tistory.com/82

 

Node.js + MongoDB 로그인 성공시 세션만들어주기(passport.serializeUser)

전글 https://daehyuntsory.tistory.com/81 Node.js + MongoDB 로그인페이지 아디 비번확인(passport passport-local express-session[lib]) 준비1. 일단 로그인 & 세션생성을 도와줄 라이브러리 설치가 필요합니다. npm install p

daehyuntsory.tistory.com

 


 

로그인 유저만 접속할 수 있는 페이지를 만들고 싶다면 어떻게 할지 알아보도록 합시다. 

예제로 가장 간단한 마이페이지를 만들어봅시다. 

 

1. 마이페이지.ejs를 만들고 라우팅을 합시다. 

(mypage.ejs)

<p>~~의 마이페이지입니다.</p>

 

그럼 이제 서버에서 /mypage 접속시 이 페이지로 라우팅을 시켜주도록 합시다. 

(server.js)

app.get('/mypage', function (요청, 응답) {
  응답.render('mypage.ejs', {})
}) 

끝입니다. 이제 /mypage 접속하면 누구나 mypage.ejs를 보여주죠?

 

2. 로그인한 사람만 마이페이지를 보여줍시다. 

지금은 마이페이지를 개나소나 다 접속이 가능한데..

로그인한 유저만 이 페이지를 보여주고 싶기 때문에 여기다가 미들웨어를 하나 추가하려고 합니다.

미들웨어는 누가 mypage를 요청시 mypage.ejs를 응답해주기 전에 실행할 짧은 코드를 의미합니다. 

그 미들웨어에서 "야 너 로그인했니?" 라고 물어보면 좋지 않을까요? 

그럼 미들웨어를 만들어봅시다. 

(server.js) 

app.get('/mypage', 로그인했니, function (요청, 응답) { 
  console.log(요청.user); 
  응답.render('mypage.ejs', {}) 
}) 

function 로그인했니(요청, 응답, next) { 
  if (요청.user) { 
    next() 
  } 
  else { 
    응답.send('로그인안하셨는데요?') 
  } 
} 

server.js 를 위와 같이 업데이트 했습니다. 

1. get() 이런 함수 안에 저렇게 미들웨어를 집어넣을 수 있습니다. 그러면 /mypage 요청과 mypage.ejs 응답 사이에 로그인했니라는 코드를 실행시켜줍니다.  

2. 로그인했니() 라는 코드는 함수입니다. 밑에서 함수를 디자인해봤습니다. 

이 함수는 "요청.user 가 있으면 next()로 통과시켜주시고요, 없으면 에러메세지를 응답.send() 해주세요~" 라는 뜻입니다. 

 

3. 요청.user 라는건 뭡니까?

로그인 한 유저의 DB상 정보입니다. (아이디, 비번, 유저명 등)

하지만 그냥 출력해보면 아무것도 없고, 이걸 사용하려면 deserializeUser 라는 부분 기능개발이 필요합니다. 

deserializeUser 라는 부분은 고객의 세션아이디를 바탕으로 이 유저의 정보를 DB에서 찾아주세요~ 역할을 하는 함수입니다. 

그리고 그 결과를 요청.user 부분에 꽂아줍니다. 

 

그래서 deserializeUser 부분을 이렇게 바꿔주시면 됩니다. 

passport.deserializeUser(function (아이디, done) {
  db.collection('login').findOne({ id: 아이디 }, function (에러, 결과) {
    done(null, 결과)
  })
}); 

그러면 DB에서 {id : 세션아이디에 숨겨져있던 유저의 아이디} 하나 찾아서 

그 찾은 DB데이터 결과를 done(null, 결과) 이렇게 해줍니다.

그러면 결과가 요청.user 부분에 꽂히게 됩니다. 

중간중간 궁금한 변수나 파라미터같은게 있으면 항상 console.log()로 출력해보시면 됩니다. 

 

아무튼 그래서, 누군가 mypage로 요청시

방문자가 세션아이디 쿠키가 존재하면 deserializeUser 라는 함수 덕분에 항상 요청.user라는 데이터가 존재합니다. 

출력해보시면 로그인한 유저의 정보가 나오쥬?

아무튼 결론은 

요청.user는 deserializeUser가 보내준 그냥 로그인한 유저의 DB 데이터입니다. 

 

그래서 로그인/비로그인 시 /mypage 방문 테스트를 해보시면 되겠습니다. 

로그아웃을 하고 싶다면 직접 브라우저 우클릭 - 검사창 열어서 - 쿠키를 삭제하시면 됩니다. 

멋지게 로그아웃시키는 방법은 누군가 /logout 페이지 방문시(GET 요청시) 요청.logout() 이라는 짧은 코드를 실행하시면 됩니다.

server.js에 하나 작성하시면 되겠습니다. 

(작성할 때 까먹지 말고 응답도 꼭 해주셔야합니다) 

 

4. 마이페이지 방문시 유저의 이름을 HTML에 박아넣고 싶어요

 

그것은 매우 쉽게 구현할 수 있습니다. 

왜냐면 아까 요청.user 라는 이상한 듣도보도 못한 변수에 유저의 데이터가 다 담겨있다고 했죠? 

app.get('/mypage', 로그인했니, function (요청, 응답) {
  console.log(요청.user);
  응답.render('mypage.ejs', { 사용자: 요청.user })
}) 

그러면 그 요청.user 라는 데이터를 mypage.ejs에 전송하면 되는게 아닐까요?

그럼 mypage.ejs에 지금 요청.user라는 데이터를 사용자라는 이름으로 전송하고 있습니다. 

그럼 이제 mypage.ejs 파일에서 이 데이터를 자유롭게 원하는 자리에 박아넣고 그럴 수 있겠군요. 

 

(mypage.ejs)

<p> <%= 사용자.id %>의 마이페이지입니다.</p>

mypage.ejs 파일을 이런 식으로 업데이터하시면 요청.user 데이터가 쏙 박히게 됩니다.  

여긴 사용자의 아이디/ 비번 이런 정보들이 들어가있겠군요. 

끝입니다. 

 


 

회원가입 기능만 한번 직접 만들어보시길 바랍니다. 

누군가 회원가입 POST 요청을 하면, 

회원가입 form에 입력했던 아이디/ 비번/ 이름 이런 정보들을 DB(login이라는 콜렉션)에 저장시키면 됩니다.

하지만 저장하기 전에 아이디가 이미 DB에 있는지 중복검사도 한번 해주면 좋겠죠?

그리고 비밀번호를 저장할 땐 비밀번호를 암호화해서 저장하는 것도 매우 좋은 관습입니다. (라기보단 그냥 필수죠)

암호화하는 라이브러리를 하나 찾아서 그대로 따라하시면 되겠습니다. 

 

그럼 DB에 qwer1234 라는 멋진 패스워드를

qwer1214 -> 35d91262b3c3ec8841b

뭐 이런 식으로 암호화해서 저장할 수 있습니다.  

 

그리고 로그인할 때도 지금은 사용자가 입력한 비번을 그대로 DB와 비교하고 있는데

사용자가 입력한 qwer1234 비밀번호를 

qwer1214 -> 35d91262b3c3ec8841b

이런 식으로 암호화해서 DB에 있는 암호화된 비번과 같은지 비교하면 되겠죠?

 

Q & A

Q. 내가 이런 기능을 만들고 싶은데 동작 프로세스를 어떻게 짜야할지 모르겠어요.

A. 시작은 벤치마킹입니다. 비슷한 프로세스를 가진 사이트를 구경해보십시오.

쇼핑몰을 만들고 싶다면 쇼핑몰 관리자 페이지를 구경해보십쇼. (요즘은 무료 쇼핑몰개설 사이트 많으니까요)

그 사이트에 나와있는 페이지와 프로세스를 똑같이 따라 구현하시면 기능개발 끝입니다. 

 

 

Q. 실제 서버 제작을 위해 신경쓰거나 더 공부해봐야할 사항들이 있나요? 

- 디자인, UI 개발, IE 호환성, 반응형 웹 등 프론트엔드 내용

- 악성 유저가 아이디를 너무 길거나 이상하게 적으면 어떻게 할지 (직접 악성 유저가 되어 이것저것 테스트해보시면 됩니다)

- DB에 저장하기 전에 빈칸이 없는지, 길이가 너무 길지 않은지 정규식과 if문으로 검증하기 

- helmet 라이브러리 등으로 보안 약간 더하기

- 이미지 업로드 등 서버에서 이미지 처리하기 (압축, 저장, 리사이즈 등)

- Oauth 등 다른 로그인 방식 도입해보기

- express-session 라이브러리는 세션이 많아지면 서버의 메모리를 많이 잡아먹기 때문에 connect-mongo 등의 라이브러리로 DB에 세션데이터를 저장해서 사용하기 

 

등 여러분이 필요한 서비스에 따라 많은 것들이 달라질 수 있습니다.