Enjoy Programming

Express - PassportJS(Node.js) --- 정리 필요 (cookie && session) 본문

JavaScript/Node.JS

Express - PassportJS(Node.js) --- 정리 필요 (cookie && session)

LEETAEEON 2021. 5. 11. 23:22

사용자 인증을 구현해 줄 passport js

 

쿠키 : 브라우저에 저장할 수 있음 , 모든 request에 대하여 back-end로 전송될 정보들이 담겨 있음

예를 들어 회원 가입 정보같은 것을 유저가 입력하고 submit하면 쿠키의 형태로 브라우저에 담기고 브라우저는 이 쿠키들을

서버로 자동적으로 보내준다.

 

passport는 쿠키를 생성하고, 브라우저에 저장하고 유저에게 해당 쿠키를 전송한다.

 

passport-local-mongoose 모듈 : 사용자 기능을 추가 (user functionality)

------------------------------------------------------------

user model 생성

 

passport-local-mongoose 설치 ( 패스워드 설정, 확인등을 자동으로 해줌)

inpm install passport-local-mongoose

 

User.js 에 임포트 해주고 UserSchema에 플러그인 해줌

passportLocalMongoose는 configuration object(설정객체)가 필요함.

------------------------------v---------------

아직 인증이 된게 아님.

passport.js를 만듬(root folder) - 

passport-local을 설치. (차후 facebook, github등등을 npm으로 다시 설치해줌

 

import passport

import User &&  passport.use()안에 strategy를 설정

strategy란 passport에게 passportLocalMongoose의 에 정의된 로그인 방식이다 (여기서의 의미- 전체적으로는 그냥 정의?)

// createStrategy()는 이미 구성된 passport-local의 localStrategy를 생성

passport.use(User.createStrategy());

*(serialization) - 어떤 정보를 쿠키에게 줄 것인지.  웹브라우저 (클라이언트)에 있는 사용자에 대해서 어떤 정보를 가져 올것인지.

deserialize - 그 쿠키의 정보를 어떻게 사용자로 전환하는가 

user.id로만 전송하고 받는다.

passport.serializeUser(User.serializeUser());

passport.deserializeUser(User.deserializeUser());

 

----------------

globalRouter.js - > postJoin 수정 (인증정보 체크하는 미들웨어 하나 삽입)

userController.js 에서 join컨트롤러로 유저정보 register & login기능 만듬

user객체에 User({})를 통해 이름과 이메일을 담아주고  User.register로 user.password를 등록

 

mongodb에가서 user collection을 확인. 정보가 담겨있음

salt와 hash 는 password를 암호화 시켜준거

현재 레지스터는 진행이 되었지만 아직 로그인 되지는 않았다. 자동로그인으로 결정

----------------------

 

 

Express - Loggin the User in

자동 로그인을 시켜주기위해 postJoin컨트롤러에 next를 매개변수로 활용하여

미들웨어로 바꿔준다.

그리고 레지스터가 되면 next()를 사용하여 다음으로 넘겨준다

이때 redirect하지않고 아에 로그인을 시켜줄 예정이므로 redirect하는 랜더링을 빼자.

 

그리고 기존 postlogin 컨트롤러를 수정해주자.

그리고 globalRouter에 post join라우터를 수정하는데 postJoin이 실행된후 postLogin 컨트롤러가 실행되도록 수정한다

 

그리고 기존 postLogin 컨트롤러를 수정하는데 passport를 이용해 인증한다 

export const postLogin = passport.authenticate("local", {

failureRedirect: routes.Join,

successRedirect: routes.home,

});

여기서 local은 앞서 설치한 passport-local startegy이다.

그리고 인증에 성공과 실패에 따라 redirect하는 곳을 설정해주는데 성공하면 홈으로 실패하면 다시 가입페이지로 가도록 설정한다.

 

이제 기존에 설정한 로컬 미들웨어를 수정해주자

기존에는 가짜 인증을 만들어서 로그인 시켜놨었기에 삭제후 req.user를 써주자

passport가 user정보를 object로 만들어서 이정보를 request에 올려준다. 이로써 template들이 local로  유저정보에 접근할 수 있게 해준다. 그리고 app.js에서 passport를 가져와서 사용해야 한다.

app.js에서 임포트해주고

로컬미들웨어 위에 

app.use(passport.initialize());

app.use(passport.session());

를 작성해주자 이렇게 하면 위에 실행된 cookieParser로부터 쿠키가 쭈욱 내려와서 passport.initialize()를 만나서 initialize시켜주고

passport가 스스로 쿠키를 들여더봐서 그 쿠키 정보에 해당하는 사용자를 찾아준다.

그리고 passport는 찾은 사용자를 request의 object 즉 미들웨어에  req.user로 만들어 준다.

그렇게 하면 user object를 template에 추가시켜 줄 수 있다.

예를 들어 header 템플릿에 조인과 로그인 부분에

이전에 선언한 !user.isAuthenticated 즉 유저가 인증 여부에 따라 뿌려줄 html을 결정했는데

이것을 수행할 수있게된다.

 

확인해보자.. 근데 문제가.. 미들웨어에 req.user만 설정했기 때문에 유저정보가 없으면 템플릿을 뿌려줄 수 없다.

req.user || {};로 바꿔서 유저 정보가 없을때는 빈배열을 주자.

 

한가지 빼먹은게 있는데 passport를 app에 import하지 않았다.

 

.... 안된다... ㅡㅡ;; 일단 홈으로 redirect까진 되지만 쿠키정보가 저장되지 않았다..

express session을 설치 하지 않았다. session관리를 위해 필요한 것이다... 

아 .. 일단 요거 오늘 할수 있는데까지 하고 쿠키와 session을 더 알아보자.. 사용법은 알았으니 넘어 갈수 있지만

제대로 알고 넘어가자. 오늘 포스팅할게 많다. 요몇일 공부에 집중하느라 포스팅을 못했는데 갈수록 밀린다...

 

 

---------------------------------------------------

Session on Express

express session 설치 npm i express-session

app에 import해주고

passport로 initialize 및 session을 저장해주기 전에 사용해준다

app.use(session({}) 그리고 option을 지정해주는데 쿠키나 도메인을 원하는데로 바꿔줄 수 있고 유효기간 같은것도 설정해 줄 수있다.

 

중요한 옵션중 secret이 있는데 random string으로 쿠키에 있는 session ID를 암호화 하기 위한 것이다.

session ID를 전송할 때 실제로 그 ID값 그대로 보내는 것이 아니다. 중요 정보이니 암호화된 상태로 보낸다.

이 secret에는 어떤 문자열을 넣든 동작을 한다.

randomkeygen.com/이 사이트에서 랜덤으로 생성된 키 하나를 가져와서

키값을 .env에 넣어주자. 중요 정보이기 때문에 환경변수 설정에 넣고 보여주지 말자. 누군가 이 정보를 보게 된다면

쿠키를 해석할 수 있고 해킹의 위험이 있다.

그리고서 process.env.변수명으로 옵션을 준다.

그리고 다시 실행하면 resave옵션이 정의 되지 않았다고 한다. 이 옵션을 주자 resave옵션은

강제로 세션을 세션store에 저장하는 옵션인듯 하다. 만약 수정이 되지 않았더라도 그냥 강제로 save시켜주는?

역할이라고 한다.

그리고 한가지더 saveUninitialized 옵션도 정의 되지 않았다고 하네... 이것도 일단 옵션을 주고

옵션값은 false로 해준다.

 다시 서버를 실행해주면~! 성공 cookie에 정보가뜬다.

근데 헤더가 바뀌지 않는걸 보니 헤더 템플릿 수정을 해줘야겠다. !user.isAthenticated를 !user로 바꿔주자

req.user이기 때문에~!

 

자 수행 순서를 보면

로그인하면 이 정보를 담은 쿠키가 express로 보내지고 express는 session을 이용해 쿠키를 가질 수 있게된다.

그리고 passport를 통해 session을 이용하는데, 즉 session이 가진 쿠키를 이용한다 

그 passport로 deserialize를 진행하는 것

passport는 deserialize한 사용자 정보를 미들웨어나 routes의 request object에 할당한다.

그렇게 어떤 라우트에서도 계속 사용자를 체크할 수 있다.

 

그런데~ 서버를 매번 새로 실행시킬 때 마다 새션의 정보가 사라진다. 그래서 로그아웃이 되어버린다.

이유는 session정보, 쿠키정보를 모두 메모리에 저장하고 있기 때문이다.

session을 유지하도록 해보자~!

 

---------------

MongoStore and Middlewares

이제 mongodb를 , 즉 데이터베이스를 사용해서 session을 저장 해보자.

connect-mongo를 다운로드하자.

MongoStore를 import해주고  CookieStore를 생성해준다. 

const CookieStore = MongoStore(session); session 오브젝트를 인자로 넣어준다.

그리고 session미들웨어에서 store옵션을 주자 new생성자로 CookieStore를 생성해주고 

CookieStore와 mongoDB를 연결해줘야 한다.

mongoose를 import 해주고

app.use(

  session({

  secret: process.env.COOKIE_SECRET,

  resave: true,

  saveUninitialized: false,

  store: new CookieStore({ mongooseConnection: mongoose.connection }),

 })

);

 

이렇게 사용해 주는데

문제는 최신 connect-mongo는 쓰는 방법이 달라져 있다. 그냥 설치후 하면 에러가 뿜뿜이기 때문에

구버전을 사용해서 진행 하고 차후 신버전으로 하는 포스팅을 하겠다.

구버전은  npm install connect-mongo@2.0.1로 설치 후 진행하면 문제가 없다.

 

자 이렇게 완료 했으면 다시 로그인하고 서버가 재시작 되도 변함 없이 로그인이 유지되고 있다.

메모리로 저장되던 쿠키와 세션 정보가 이제 mongostore에 저장되고 있는 것.

 

이제 할일은 routes를 제한을 좀 해야한다. 이미 로그인된 사용자는 가입 페이지로 접근을 못하게 하는 것.

미들웨어를 하나 더 만들자.

로그아웃 상태에서만 접근허용 미들웨어 - 만역 req.user 정보가 있으면 home화면으로 redirect 해주고

아니라면 next()를 실행한다.

 

만들어 줬으면 globalRouter로 가서 임포트 해주고 join & login라우터에 미들웨어를 삽입해주자.

 

추가로 public에만 사용하는 라우터가 있다면 private으로만 사용하는 라우터도 있다

업로드라던지 profile페이지라던지 그걸 위한 미들웨어도 하나 만들어 주자.

 

로그인 되어 있어야 되는 구역은 많기에 라우터 수정부분이 좀 많다. 근데 뭐.. 쉽다.

 

여기까지이고 다음엔 소셜 로그인 인증 파트를 다루는데 그에 앞서 포스팅 정리좀 하고 cookie와 session에 대해 짚고 넘어가자

 

'JavaScript > Node.JS' 카테고리의 다른 글

Express - Loggin the User In  (0) 2021.05.12
Express - passport JS && Local Authentication  (0) 2021.05.12
WEBPACK  (0) 2021.05.10
Express - Searching Videos  (0) 2021.05.09
Eslint (node.js)  (0) 2021.05.09