본문 바로가기

코딩/Today I Learn

12.8 공부

728x90

로그인 했을 때 template 바꾸기

로그인 했을 때 join과 login가리고 logout 표시 

그러면 템플릿에섯 세션을 접근 할 수있는가?

--> 안됨 해당 정보를 pug 템플릿과 공유하지 못한다.

 

 if !req.session.loggedIn
                        li 
                            a(href="/join") Join 
                        li 
                            a(href="/Login") Login 

안됨!!!

res Object중에 
res.locals는 pug와 express 서로가 공유 할 수있도록 설정 되어있음 
미들웨어가 router에 적용했을 때 사용됨

template과 data공유 모든 template에 전역적으로 변수를 쓸수있다. 

res.render로 안보내도 됨

 

server.js

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

 

base.pug

    body 
        header 
            h1 Who is sexy? #{sexy} //locals.같은거 안써도 됨

이렇게 출력된다.

우리가 할것 -> locals에 사용자를 추가할 것임 

모든 template에서 누가 로그인 했는지 알 수있어

 

1.middlewares.js파일을만들어서 

export const localsMiddleware = (req, res, next) => {
    console.log(req.session);
    res.locals.siteName = "Youtube";
    next();
}  ///app.use(session({})) 이 후로 localsMiddleware와야지 작동 

2.server.js에 

import와 

app.use(localMiddleware);

 

 

 

 

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

app.use((req, res, next) => {
    req.sessionStore.all((error, sessions) => {
        console.log(sessions);
        next();
    });
}); 삭제 back-end가 기억하는 모든 사람을 보고싶지 않음 

app.use(localsMiddleware); 

/// session 다음으로 미들웨어가 와서 동작하는 것 그래야 session에 접근 할 수잇으니까 

 

export const localsMiddleware = (req, res, next) => {
    res.locals.loggedIn = Boolean(req.session.loggedIn); //undefined이거나 null 일 수도 있으니까 
    res.locals.siteName = "Youtube";
    console.log(res.locals);
    next();
}

새로고침할 때마다 locals에 정보가 있음

locals는 template이 참고할 수있음

base.pug

                    if loggedIn 
                        li 
                            a(href="/logout") Logout
                    else
                        li 
                            a(href="/videos/upload") Upload video   
                        li 
                            a(href="/join") Join 

 

 

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

 

  if loggedIn 
                        li 
                            a(href="/logout") Logout
                        li
                            a(href="/my-profie") #{loggedInUser.name}의 Profile  //login되어있지않을 때는 값이 undefined이니 꼭 loggedIn 되어있을 때 사용

 

쿠키는 전달하는 방법,

쿠키안에 session ID 가있음

Server에 sessionStore가있는데 세션들의 모음이 있음(서버에 접속한 다른 브라우저들)

cookie에는 Session data가 저장되지 않는다. session ID만 저장됨

session data는 서버사이드에 저장된다.

기본으로있는 서버사이드 session stroage는 MemoryStore이고 실제사용하기위해 있는건아니다.

--> mongoDB에 저장할 것임 서버를 꺼도 세션은 database에 저장되어있기 때문에 누군가 로그인되어있어도 잊어버리질 않을 것임 

 

 

npm install connect-mongo   //세션을 몽고DB에 저장 서버가 재시작되더라도 데이터가 데이터베이스에있음 

import MongoStore from"connect-mongo";

 

app.use(session({
    secret: "Hello!",
    resave: true,
    saveUnintialized: true,
    store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:27017/youtube" })
}));

session들을 mongoDB에 저장됨 

mongo에서 check

> show collections
sessions
users
videos
> db.sessions.find({})

//아무 결과도 나오지 않음

세션이 없음 세션이 어떻게 만들어지는가?

브라우저가 backend방문할 때 

--> 방문하면 

> db.sessions.find({})
{ "_id" : "wr0IrmROceWtJpoIwgBdLkboc6Qz5jjA", "expires" : ISODate("2021-12-22T13:27:47.653Z"), "session" : "{\"cookie\":{\"originalMaxAge\":null,\"expires\":null,\"httpOnly\":true,\"path\":\"/\"}}" }
//expires하고 나온날짜 이후로user를 잊어버리겠다는 뜻

이제 서버를 재시작해도 로그인되어있음

 

세션은 디폴트로 RAM메모리에 저장되는데 렘메모리는 껏다키면 사라지니까 mongoStore로 지정해주면 몽고db 즉, 보조기억장치에 저장시켜서 껏다켜도 사라지지 않게 할 수 있는거군요

https://www.npmjs.com/package/connect-mongo

 


 

쿠키는 방문하는 모든 사용자에게 주게된다.

만약 10만명이 들어오면 10만 명 모두를 기억할 것인가? nope

기억하고 싶은 사람만 쿠키를 주자 (예) 로그인 한 사람)

익명사용자에게는 쿠키 주지않기 -->  + ios , 안드로이드앱은 쿠키를 갖지 않기 때문에 token 사용해  

 

app.use(session({
    secret: "Hello!",
    resave: true   false,
    saveUnintialized: true  false,   //saveUninitalized:false 세션이 새로만들어지고 수정될 때만 저장,

수정이란? UserController에 req.session.loggedIn= true; req.session.user = user; 이 부분 로그인하면 수정되는 부분
    store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:27017/youtube" }),

 

saveUninitialized : true < 따로 값을 설정하지 않은 전달 받은 날 것의 세션을 즉시 Store에 저장 후 세션 주인에게 쿠키를 (답장하듯) 넘겨 준다.


saveUninitialized : false < req.session 속 값을 수정하는 그 순간에 세션을 Store에 저장 후 그제야 쿠키를 전달한다.
}));

 


app.use(session({
    secret: "Hello!",  --> secret은 말그대로 숨겨줘야하고
    resave: false,
    saveUnintialized: false,
    store: MongoStore.create({ mongoUrl: "mongodb://127.0.0.1:27017/youtube" }), --> mongodb에는 아이디와 비밀번호 에대한 정보가 있기때문에 실제 배포할 때 이렇게 주소로 배포하면 안됨 ! 현재는 localhost라 상관없지만 

 

secret: 쿠키에 sign(backend가 쿠키 줬다는걸 보여주기 위해 함)할 때 사용하는 string,

session haijack 쿠키훔쳐서 자기인듯 하는 행위 때문에 길고 복잡하게 만들어야한다.

이 쿠키를 가지고sign 하고 우리가 만든 것임을 증명 할수있다.

Domain 쿠키를 만든 백엔드가 누구인지 알려줌 따라서 어디서 쿠키가왔고 요청이 왔으면 어디로가는지 말해줘

instagram 쿠키를 우린 받지않어

 

expires //session cookie : 만료가 되는 시기 적지 않을 때 나타나는 상태

사용자가 닫거나 컴퓨떠 끌 때  session coockie는 끝남 

 

max-age 언제 exprie 되는지 알려줌 브라우저가 평생 켜져있어도 만료일자가 있어서 그 때까지만 쿠키가 저장됨  

sescret 과 storre의 mongoUrl를 보이지 않게 하고싶음 1000ms 단위 은행로그아웃 되는 것처럼 

  app.use(

   session ({

     cookie:{

       maxAge:2000,

   })

 )

 

.env라는 파일을 만들어 환경변수를 만들고 .gitignore에 추가 

코드에 들어가면 안될 값들을 넣을 것임(secret,mongodb url) 

관습적으로 모두 대문자로적어야함 

 

COOKIE_SECRET=fdsjflkd5353443sfjdlskfsd
DB_URL =mongodb://127.0.0.1:27017/youtube 따옴표 넣으면 안됨

 

env파일에 접근 할 때는 

 

app.use(session({
    secret: process.env.COOKIE_SECRET,
    resave: false,
    saveUnintialized: false,
    store: MongoStore.create({ mongoUrl: process.env.DB_URL }),
}));

 

 

db.js 

mongoose.connect(process.env.DB_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true,
}); //mongoose가 database와 연결 해줌 

 

하지만 아직process.env.무엇 

을 읽을 수없음 

dotenv 설치 npm i dotenv

파일을 읽고 env를 추가해줌 

가능한 빨리 env를 로드해야해서 제일 윗줄에 설치  server.js

require("dotenv").config();

 

그래도 env를 읽을 수 없음 가장먼저 설치되지 않았기 때문 

package.json에 보면 src/init.js가 가장먼저 실행됨

따라서 init.js 첫 줄에 실해 ㅇ--> 여전히 에러 

require 방식은 process.env를 사용하는 모든 파일! 윗줄에 작성해줘야하기 때

그래서 지우고 init.js에 import "dotenv/config"; 

 

이제 깃에 올라가지도 않고 이 파일에만 존재함 ! 

중요한 것을 숨기는 방법 

 

 

https://www.npmjs.com/package/dotenv

import dotenv from "dotenv", dotenv.config() 대신
import "dotenv/config"로 바로 dotenv config함수를 불러와서 실행 가능

'코딩 > Today I Learn' 카테고리의 다른 글

12.15 공부  (0) 2021.12.15
12.9 공부  (0) 2021.12.14
12.7공부2  (0) 2021.12.07
12.7 공부  (0) 2021.12.07
12.6 공부  (0) 2021.12.06