Logged In User #02

Response object에서 알아야 할게 있다.

이걸 알기 위해 session을 알기 위해 썼던 middleware을 사용해서

server.js에서

app.use((req, res, next) => {
  console.log(res);
  req.sessionStore.all((error, sessions) => {
    console.log(sessions);
    next();
  });
});

resonse objectconsole.log한다. 그리고 확인해본다. 새로고침을 하니까 에러가 있다.

상관없다. node를 보면 console.log된게 많이 있다.

Response object에서 알고 싶었던 것은 locals라는 거다.

 locals: [Object: null prototype] {},

보다시피 현재 locals는 비어있는 object이다.

이 비어있는 object는 좋은 소식이다. pug template에서 locals에 접근할수 있다.

이건 기본적으로 되는거다. 별 다른 걸 할 필요가 없다. pugExpress가 서로

locals를 공유 할수 있도록 설정되어 있다.

이게 무슨 뜻이냐면 locals object를 바꾼다고 한다면 template에서 locals object

내용을 확인 할수 있다는 거다. 한번 확인해 보도록 한다.

app.use((req, res, next) => {
 res.locals.sexy = "you";
 req.sessionStore.all((error, sessions) => {
   console.log(sessions);
   next();
 });
});

이렇게 locals object에 딱하나를 추가했다. 모든 pug파일들은 locals object에 접근할수 있다.

그리고 base.pug에서도 변경해준다.

body 
        header
            h1 Who is sexy? #{sexy}
            nav 
                ul 
                    li  
                        a(href="/") Home
                    li 
                        a(href="/join") Join
                    li 
                        a(href="/login") Login
                    li  
                        a(href="/search") Search
                    li 
                        a(href="/videos/upload") Upload Video

그리고 이번을 위해서만 pageTitle을 변경해 준다.

Who is sexy? 라 쓰고 #{sexy}를 쓴다. 그냥 이렇게 써주면 된다. locals.같은건 안써도 된다.

작동하는지 본다. pageTitle"Who is sexy? you"라고 출력이 되었다.

이런 방식으로 templatesdata를 공유하는거다. 그리고 이거는 global(전역변수)라서

모든 template에서 쓸수 있다. 보다시피 이 title은 바뀌지 않고 있다.

다른 곳으로 넘어가도 계속 유지 되고 있다. 그리고 localstemplate의 모든 곳에 있다.

물론 middlewarerouter에 적용을 했을 때에 한해서 말이다.

이제 template에서 sexy라는 변수를 쓸수 있다.

굉장히 좋은 소식인거다. 왜냐하면 template변수를 전역적으로 보낼수 있다는 뜻이다.

변수들을 res.render로 보내지 않아도 된다. 그냥 locals objecttemplate에 변수를

전역적으로 보낼수 있다.

다시 말하자면, locals object는 이미 모든 pug templateimportobject이다.

이렇게도 해볼수 있다.

app.use((req, res, next) => {
  res.locals.sexy = "you";
  res.locals.siteName = "Wetube";
  req.sessionStore.all((error, sessions) => {
    console.log(sessions);
    next();
  });
});

그리고 base.pug에서는

head
        title #{pageTitle} | #{siteName} 

이렇게 바꿔 준다. 다시 한번 강조하지만 이는 locals object안에 있어야 한다.

새로고침하면 Wetube가 잘 적용되고 있다.

app.use((req, res, next) => {
  res.locals.sexy = "you";
  res.locals.siteName = "xxxxxXXXXX";
  req.sessionStore.all((error, sessions) => {
    console.log(sessions);
    next();
  });
});

다시 이렇게 변경한 다음에 새로고침하면 xxxxxXXXXX로 적용되어서 나오고 있다.

이게 locals object고 정말 유용하다. 왜냐하면 locals에 로그인한 사용자를 추가하는 거다.

이 뜻은 template이 누가 로그인 했는지 알수 있다는 거다.

siteName같은 것도 정말 유용하다. 그래서 middleware을 만들거다.

pageTitle로 돌아가 본다. middleware를 만들어 본다.

src폴더 안에 middleware파일을 만들어 준다.

middlewarelocalsMiddleware라고 해준다.

export const localsMiddleware = (req, res, next) => {
  res.locals.siteName = "Wetube";
};

req,resnext를 받을거고 여기에 locals를 설정해 본다. 몇개의 locals을 설정해주는것이 다다.

예를 들어 siteName 그리고 Wetube라고 해준다.

이게 middleware이다. localsMiddleware이다.

server.js에서

import { localsMiddleware } from "./middleware";


app.use((req, res, next) => {
  req.sessionStore.all((error, sessions) => {
    console.log(sessions);
    next();
  });
});

app.use(localsMiddleware);

이렇게 수정해 주고 app.use(localsMiddleware);추가해주면 자동으로 import가 되지 않아서

따로 해주었다.

이제 middlewares파일에 만들 모든 middleware를 추가해 준다.

이제 다음으로 할 일은 정해졌다. locals을 통해 누가 로그인했는지 공유하는거다.

그러면 한번 더 로그인 해본다. 그전에 여기에서 req.sessionconsole.log해본다.

export const localsMiddleware = (req, res, next) => {
  console.log(req.session);
  res.locals.siteName = "Wetube";
  next();
};

새로고침을 하고 로그인을 하고 콘솔창으로 가보면

Session {
  cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true },
  loggedIn: true,
  user: {
    _id: '625942ace3564e09811a5f21',
    email: '[email protected]',
    username: 'Cyber Lover',
    password: '$2b$05$WMO/VH/yctvvPJST0SyLq.QRQfSNeLJ5zAJPFfRMwLgg5ZFq1KtBm',
    name: 'Mercury',
    location: 'NYC',
    __v: 0

session이 있고 cookie, loggedIn, user가 있다.

[Object: null prototype] {
  tW3l1LCHc8Zc0urTdDkEnlo1xRh2uhV7: {

이게 middleware이고, 위 부분이 locals로부터 온 내용이다.

보다시피 localsMiddlewarereq.session을 접근 할수 있다.

그리고 다시 강조하지만 정말 중요하다.

이건 localsMiddlewaresession middleware다음에 오기 때문에 가능한거다.

app.use(
  session({
    secret: "Hello!",
    resave: true,
    saveUninitialized: true,
  })
);

만약 localsMiddleware을 이곳으로 옮기면

app.set("view engine", "pug");
app.set("views", process.cwd() + "/src/views");
app.use(logger);
app.use(express.urlencoded({ extended: true }));
app.use(localsMiddleware);


app.use(
  session({
    secret: "Hello!",
    resave: true,
    saveUninitialized: true,
  })
);

session은 나타나지 않는다.

undefined
[Object: null prototype] {}

콘솔창에 이렇게 나온다.

이제 localsMiddlwaresession middelware다음에 있다.

그래야 localsMiddlewaresession object에 접근 할수 있다.

다시 새로고침해서 확인해 보면 콘솔을 확인해 보면

[Object: null prototype] {}
Session {
  cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true }
}

session이 출력된다.

그리고 이제 이 middleware는 지워준다.

app.use((req, res, next) => {
  req.sessionStore.all((error, sessions) => {
    console.log(sessions);
    next();
  });
});

백엔드가 기억하고 있는 모든 사람들을 오직 하나만 보고 싶다.

그러면 여기서 session을 확인해 본다. 콘솔창을 확인해 보면

Session {
  cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true }
}

로그인 하기전에 이 부분을 뭔가를 해준다.

export const localsMiddleware = (req, res, next) => {
  res.locals.loggedIn = Boolean(req.session.loggedIn);
  res.locals.siteName = "Wetube";
  console.log(res.locals);
  next();
};

로그인 되어 있을때 어떻게 보이는지 한번 보기로 한다. 만약 req.sessionloggedIntrue라면

if(req.session.loggedIn){
  res.locals.loggedIn = true;
}

이거를 좀더 수정을 해주면 이렇게 할수도 있다.

res.locals.loggedIn = req.session.loggedIn;

그런데 이 값이 false이거나 undefined 일수도 있으니

Boolean()을 사용해서 이 값이 true이거나 false인지 확인한다.

  res.locals.loggedIn = Boolean(req.session.loggedIn);

그래서 이렇게 나왔다.

그리고 이제 res.localsconsole.log()로 찍는다.

어떤 결과가 나오는지 본다. 다시 한번 새로고침을 해준다.

코드를 저장하고 보다 나은 세션 저장소를 설정하지 못했기 때문이다.

모든 세션이 사라졌다.

[Object: null prototype] { loggedIn: false, siteName: 'Wetube' }
GET / 304 191.753 ms - -

이걸 보면 알수 있듯이 이 값들이 locals이다. 매번 새로고침을 할때 마다

locals가 있다. 이제 이 objecttemplate와 공유 되고 있다는 것을 알았다.

그래서 이게 무슨 뜻이냐 하면

                    li  
                        a(href="/") Home
                    if loggedIn
                        li 
                            a(href="/logout") Log Out        
                    else 
                        li 
                            a(href="/join") Join
                        li 
                            a(href="/login") Login

이 부분에서 만약 로그인이 되어 있다고 한다면 무언가를 보여줄 것이고

아니라면 이것들을 보여줄거다. 만약 user가 로그인 되어 있는 상태라면

로그아웃 버튼이 보이도록 할거다. 그리고 logout이라고 적는다.

pug파일에서 locals에 접근할수 있다는걸 꼭 기억 한다.

만약 locals에 어떤 값을 준다면 pug가 읽을수 있다. 이게 바로 locals이다.

loggedIn의 값은 false이고 siteName의 값은 Wetube이다.

[Object: null prototype] { loggedIn: false, siteName: 'Wetube' }
GET / 304 191.753 ms - -

로그인해서 어떻게 나오는지 본다. 로그인이 되었고 logout이 생겼다.

[Object: null prototype] { loggedIn: true, siteName: 'Wetube' }
GET / 200 57.525 ms - 593

콘솔을 확인해서 보면 locals를 보면 loggedIn: true라고 나온다.

이제 로그인이 되어있는거다. 새로고침해도 유지되고 있다.다른 브라우저로 가본다.

보다시피 여기에서는 로그인 되어 있지 않다. 방근 인증 시스템을 만든거다.

Login,join,비밀번호 암호화 이제 express로 세션도 다루고 쿠키도 다루고

유저들간에 구별도 할수 있다.

req.sessionuser가 있다는 걸 기억한다. 여기를 보면 req.sessionuser가 있다.

[Object: null prototype] {
  tW3l1LCHc8Zc0urTdDkEnlo1xRh2uhV7: {
    cookie: { originalMaxAge: null, expires: null, httpOnly: true, path: '/' },
    loggedIn: true,
    user: {
      _id: '625942ace3564e09811a5f21',
      email: '[email protected]',
      username: 'Cyber Lover',
      password: '$2b$05$WMO/VH/yctvvPJST0SyLq.QRQfSNeLJ5zAJPFfRMwLgg5ZFq1KtBm',
      name: 'Mercury',
      location: 'NYC',
      __v: 0
    }

이 값을 template와 공유 할수 있다. 한번 해보도록 한다.

export const localsMiddleware = (req, res, next) => {
  res.locals.loggedIn = Boolean(req.session.loggedIn);
  res.locals.siteName = "Wetube";
  res.locals.loggedInUser = req.session.user;
  next();
};

이 값은 처음에 undefined 일거다. 왜냐하면 로그인 되어 있지 않기 때문이다.

코드를 저장해 본다. 새로고침하면 보다시피 다시 로그아웃 되었다.

이 부분은 다음 파트에서 하기로 한다. 그러기 전에 일단 이 쪽으로 와서 navigation

li  
                        a(href="/") Home
                    if loggedIn
                        li 
                            a(href="/logout") Log Out
                        li 
                            a(href="/my-profile") #{loggedInUser.name} Profile
                    else 
                        li 
                            a(href="/join") Join
                        li 
                            a(href="/login") Login

a(href="/my-profile")이거 아직 존재하지 않는다.

base.pug에서 뭘 한거냐면 로그인이 되어 있다면 logout 버튼을 보여주고

locals middleware덕분에 loggedInUser를 공유하고 있다.

이건 req.session.user; undefined 일 수도 있으니까

user가 로그인 되어 있지 않을때 loggedInUser를 사용하면 안된다.

그런데 이 부분에서는 user가 로그인 되어 있는게 확실하다.

그래서 로그인 되어 있다면 loggedInUser값이 있다는 뜻이니까

loggedInUser.name을 사용할수 있다. 왜냐하면 loggedInUsername이 있다는걸 안다.

다시 한번 시험해 본다. 다시 로그인 하면 해당 유저의 이름 + Profile이라고 뜬다.

이제 이 값을 template의 모든 곳에 공유 하고 있다.

현재 ProfileLogOut은 없다. 보다시피 이 값을 template와 공유 하고 있다.

방금 로그인 시스템을 만들었다. SessionCookie,패스워드 암호화, 패스워드 비교를 이용해서 말이다.

그리고 locals을 사용해서 변수를 pug 전역에서 사용하는 법을 배웠다.

코드를 저장할때 마다 Session은 초기화 된다는걸 꼭 기억하자.

코드를 새로 저장하고 홈페이지로 가서 새로고침 하니 로그아웃이 되었다.

현재는 코드를 저장 할때마다 session은 사라진다. 그리고 서버는 유저에 대해서 잊어버린다.

좋은 웹페이지 즐겨찾기