- HTTP 쿠키는 서버가 사용자의 웹 브라우저에 전송하여 저장하는 작은 데이터 저장소
- JS의 객체처럼 key 값과, data 가 들어 있습니다
- 브라우저는 쿠키로 데이터를 저장해 두었다가, 동일한 서버에 다시 요청을 보내게 될 때 쿠키에 저장된 정보를 함께 전송합니다
- 따라서, 서버에서는 쿠키를 통해 요청이 어떤 브라우저에 들어왔는지(혹은 요청이 동일한 브라우저에서 들어왔는지) 등을 파악할 수 있습니다
- 서버에 저장 해야할 정보를 관리 -> 로그인 정보, 장바구니, 팝업 하루 동안 안보기 등
- 중요한 정보는 아무래도 로컬에 남게 되므로 절대 저장해서는 안됩니다
- 중요 정보로는 이름, 데이터, 만료일, 경로 등이 저장 됩니다
cookie의 동작방식
사용예시
프론트에서 쿠키 사용하기
- Document.cookie 로 바로 만들어서 사용하면 됩니다
- Expires 값과 브라우저의 시간을 비교해서 쿠키가 해당 시간이 되면 자동으로 삭제 처리
- 쿠키 여부를 체크해서 이런 방식으로도 사용이 가능합니다
- 프론트의 JS 코드를 통해 특정 상황에서 페이지가 새로 고침해도 저장이 필요한 정보를 쿠키에 저장하여 DB처럼 활용도 가능합니다
- 다만, 딱히 쓸 일이 많지는 않습니다!
브라우저에서 쿠키 확인하기
- 개발자 도구 -> Application -> Storage -> Cookies 에 가면 쿠키 정보 확인이 가능합니다
백엔드에서 쿠키 사용하기
- 백엔드에서는 cookie-parser 라는 모듈을 사용합니다!
- 일단 설치
npm i cookie-parser -s
- 메인 서버에 쿠키 모듈 호출 및 미들 웨어 등록!
- 이제 쿠키를 사용할 곳에서 res.cookie(‘쿠키 이름‘, ‘데이터’, ‘옵션 객체‘); 를 써서 사용하면 됩니다!
- 옵션의 의미
- Expires: 쿠키가 자동으로 삭제되는 일자를 지정
- httpOnly: 해당 쿠키는 서버와의 http 통신에서만 읽을 수 있음을 표시, 프론트에서 처럼 JS로 해당 쿠키를 읽으려 하면 웹브라우저가 이를 차단
실제로 쿠키 잘 작동하는지 확인
- Index.ejs 에서 cookie가 서버에서 잘 전송 되었는지 확인해 봅시다!
- 먼저 프론트에서 쿠키를 발행하는 코드는 주석 처리 + 기존에 발행 된 쿠키도 삭제 처리
- 안되는 이유는 httpOnly 옵션 때문에 document.cookie 의 값을 읽으려고 하는 것을 브라우저가 차단하기 때문입니다.
- httpOnly 옵션을 false 로 만들고 다시 해봅시다!
쿠키 값 전달
- 쿠키를 생성하면서 쿠키의 값을 res.render 에 담아 같이 전달해서 사용도 가능합니다!
- 생성된 쿠키에 대한 접근은
req.cookies.쿠키이름
으로 하면 됩니다
- httpOnly 옵션이 켜져 있음에도 값을 전달 하였기 때문에 alert 창이 잘 뜨는 것을 볼 수 있습니다!
- 단, 쿠키 내용은 안뜹니다!
실습, 팝업창 하루동안 닫기 구현
팝업이 뜬 상황에서 오늘 하루 안보기를 체크하고 닫기를 누르면 쿠키를 발행하고, 해당 쿠키에 의해 팝업이 하루동안 안보이도록 구현!
<script>
의 if 문 내부의 조건 채우기 부분 + modalClose() 함수의 //하루 동안 안보기 기능 구현하기 부분을 구현!
Index.js 라우터에서 /cookie 라는 주소를 POST 방식으로 받고 팝업창을 하루동안 안띄워주는 쿠키를 발행
Index 페이지를 render 할 때, 쿠키의 값을 전달해서 처리
index.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index', { popup: req.cookies.popup });
});
router.post('/cookie', (req, res) => {
res.cookie('popup', 'hide', {
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
httpOnly: true,
});
res.send('쿠키 생성 성공');
});
module.exports = router;
index.ejs
<script>
const myModal = new bootstrap.Modal('#exampleModal');
if( '<%= popup %>' === '') myModal.show();
function modalClose() {
if(document.getElementById("cookie").checked){
fetch('cookie', {
method: 'post',
headers: {
'Content-type' : 'application/json'
},
}).then((res)=> {
console.log(res.data);
}).catch((err)=> {
console.log(err);
})
}
myModal.hide();
}
</script>
Session(서버의 쿠키)
HTTP Session이란
- 브라우저가 아닌 서버에 저장되는 쿠키
- 사용자가 서버에 접속한 시점부터 연결을 끝내는 시점(로그아웃/브라우저 닫기)을 하나의 상태로 보고 유지하는 기능을 함 -> 로그인 유지
- 서버는 각 사용자에 대한 세션을 발행하고 서버로 접근(Request)한 사용자를 식별하는 도구로 사용
- 로컬 저장이 아니라 서버에 저장되기 때문에 서버를 해킹되지 않는 이상 보안성이 좋음
- 쿠키와 달리 (서버에 저장되기 때문에)저장 데이터에 제한이 없음
- 만료 기간 설정이 가능하지만, 브라우저가 종료되면 바로 삭제
HTTP Session의 동작 방식
- 사용자가 최초로 서버 연결을 하면 하나의 Session-ID(임의의 긴 문자열) 가 발행 됩니다
- 발행 된 Session-ID 는 서버와 브라우저의
메모리
에 쿠키 형태로 저장이 됩니다 => 휘발성이 있다. (RAM 같음)
ROM은 데이터가 기록이 계속되는 것
RAM은 전기가 나가거나 컴퓨터가 꺼졌다 켜지면 날아가는 정보
- 서버는 사용자가 서버에 접근 시, 쿠키에 저장 된 Session-ID를 통해서 서버는 사용자를 구분하고 요청에 대한 응답을 합니다
Cookie vs Session
- 하는 역할은 비슷
- 쿠키는 로컬에 저장 되므로 보안 이슈가 발생 가능
- 세션은 로컬에 session-id 만 저장하고, 데이터는 서버에서 처리하므로 보안이 더 좋음
- 단, 쿠키는 데이터를 바로 저장하고 있으므로 속도가 빠름.
- 세션은 쿠키에서 session-id 를 읽어서 서버에서 데이터를 받아야 하므로 속도는 더 느림
- 세션아이디는 쿠키를 쓰기 때문에, 세션은 쿠키에 종속적이다.
Session모듈 추가
- 먼저 express-session 모듈 부터 설치
npm i express-session -s
- 모듈 추가 및 미들웨어 연결
세션 모듈 옵션 설명
- secret: 세션을 발급할 때 사용되는 키 값(아무거나 입력 가능)
- resave: 모든 request 마다 기존에 있던 session에 아무런 변경사항이 없어도 session 을 다시 저장하는 옵션 (보통 false를 쓴다.)
- saveUninitialized: 세션에 저장할 내역이 없더라도 처음부터 세션을 생성할지 설정 (로그인을 했을 때 세션이 있어야 관리 편함 true로 )
- secure -> https 에서만 세션을 주고받을 수 있습니다. http 에서는 세션을 주고받는 것이 불가능
- cookie : 세션 쿠키 설정 (세션 관리 시 클라이언트에 보내는 쿠키)
- maxAge: 쿠키의 생명 기간이고 단위는 ms입니다.
- httpOnly -> 자바스크립트를 통해서 세션을 사용할 수 없도록 강제
Passport 모듈
-
로그인 기능을 다방면으로 도와주는 모듈입니다
-
사실 방금 전에 Session 다 배워 놓고 왜 지금 가르치냐 하실지도 모르겠지만... Session 을 알고 요걸 배우는게 중요합니다
-
그리고 (개인적으로) 이게 더 어려워요
-
대신, 요 친구는 다음 시간에 배울 Google, Facebook, Github 등 소셜 로그인 구현을 위한 기능을 제공하기 때문에 배울 필요가 있습니다
-
이때는 이게 훨 편합니다
-
http://www.passportjs.org/
-
우리는 Local 방식 -> 전통적인 아이디, 비밀번호를 입력하는 방식을 이용하므로 passport-local 도 같이 설치해 줍니다
-
passport 설치 Npm i passport
로컬방식 설치 Npm i passport-local
-
서버코드에 모듈 추가하기
-
(passport 세션을 사용) 하기 때문에 app.use passport는 꼭 session 아래에 넣어야 한다.
Passport, Local 전략 설정
- Passport 는 기본적으로 로그인을 어떤 방식으로 처리할 지 미리 정해놓습니다.
- 그리고 실제적 로그인 처리는
passport.authenticate
메소드(자격증명)를 이용하여 처리합니다.
- 아이디와 비밀번호를 어떤 키 값으로 받을지 옵션으로 설정합니다
- 그리고 인증 절차를 수행하는 함수를 설정합니다
- 인증 절차 수행의 결과는 Callback 함수에 담아서 처리를 합니다. (async/await XX)
- 복잡한 편..
Passport, serialzeUser
- Passport 도 session 을 사용하여 로그인 여부를 판단합니다
- 위에서 Callback 함수에 담긴 내용은 serialzeUser 메소드가 받아서 세션을 만들어 전달 받은 유저 정보를 세션에 저장합니다
- 해당 세션은 req.user 로 접근하셔 정보를 확인 할 수 있습니다
- 콜백 함수에 의해 user.id 부분이 세션에 저장 되는 코드!
Passport, deserialzeUser
- Passport 는 더욱 까다롭게 로그인 여부를 판단하기 때문에 로그인한 사용자가 다른 페이지에 접속하려고 할 때에도 계속 인증을 요구 합니다
- 해당 기능을 deserializeUser 가 수행
ssession 에 저장된 사용자 정보를 통해서 DB에 사용자가 실제로 있는지 꾸준히 확인하는 과정을 거칩니다.
PASSPORT 로그인 구현
-
Passport 로그인은 authenticate 메소드가 처리해 줍니다!
-
에러가 발생하면 err
매개변수에 에러 값이 담깁니다
-
로그인이 성공하면 user
에 전달한 user 정보가 담겨서 넘어옵니다
-
로그인이 실패하면user
는 null 로 리턴되며, 전달한 메시지는 info 매개변수의 객체에 담겨서 전달이 됩니다
-
매개변수를 잘 이용하면 로그인 성공/실패/문제 등등을 체크할 수 있다.