로그인 했을 때 template 바꾸기
로그인 했을 때 join과 login가리고 logout 표시
그러면 템플릿에섯 세션을 접근 할 수있는가?
--> 안됨 해당 정보를 pug 템플릿과 공유하지 못한다.
if !req.session.loggedIn
li
a(href="/join") Join
li
a(href="/Login") Login
안됨!!!
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함수를 불러와서 실행 가능