본문 바로가기

Node/Node.js교과서

[Node] express -2

express-session : 세션 관리용 미들웨어

app.use(session({
	resave:false,
    saveUninittialized: false,
    secret:process.env.COOKIE_SECRET,
    cookie:{
     httpOnly:true,
     secure:false,
    },
    name:'session-cookie',
 }));
 req.session.name = 'kimbarbie'; //세션등록
 req.sessionID; 	//세션 아이디확인
 req.session.destroy();	//세션 모두 제거

세션 쿠키에 대한 설정  (secret: 쿠키 암호화, cookie: 세션 쿠키 옵션)

세션 쿠키는 앞에 s%3A가 붙은 후 암호화 되어 프런트에 전송

 

속성설명

resave : 요청이 왔을때 세션에 수정사항이 생기지 않더라도 다시 저장할지 여부 확인

saveUninitialized: 세션에 저장할 내역이 없더라도 세션을 저장할지 여부 확인

req.session.save : 해당 기능으로 수동 저장도 가능하지만 거의 사용하지 않는다

 

httpOnly: 브라우저에서 쿠키에 접근할 수 없도록 제한한다. (HttpOnly의 기본값은 false)

이러한 역할을 하는 것이 바로 HTTP Only Cookie입니다

개발자가 다음과 같이 간단한 접미사를 쿠키생성코드에 추가함으로써 활성화 할 수 있다. 해당설정으로 XSS와 같은 공격이 차단

HTTP Only Cookie를 설정하면 브라우저에서 해당 쿠키로 접근할 수 없게 되지만, 쿠키에 포함된 정보의 대부분이 브라우저에서 접근할 필요가 없기 때문에 HTTP Only Cookie는 기본적으로 적용하는 것이 좋다.

 

Secure

HTTP Only Cookie를 사용하면 Client에서 Javascript를 통한 쿠키 탈취문제를 예방할 수 있다.

하지만, Javascript가 아닌 네트워크를 직접 감청하여 쿠키를 가로챌 수도 있다. 

이러한 통신상의 정보유출을 막기 위해, HTTPS 프로토콜을 사용하여 데이터를 암호화하는 방법이 주로 사용.

HTTPS를 사용하면 쿠키 또한 암호화되어 전송되기 때문에, 제3자는 내용을 알 수 없다 .

문제는 HTTPS로 전송되어야 할 정보가, 개발자의 부주의로 HTTP를 통해 유출되는 경우가 있다.

예를 들어 개발자가 다음과 같은 코드를 실수로 작성할 수 있습니다.

<img src="http://www.example.com/12345.png">
 

브라우저는 http://로 시작되는 위 코드를 만나면 암호화되지 않은 상태로 쿠키를 서버로 전달한다.

해커는 이 암호화되지 않은 요청정보를 가로채서 쿠키를 탈취하게 되는것이다.

이러한 사고를 방지하는 방법은 쿠키를 생성할 때 secure 접미사를 사용한다.

 

위와 같이 마지막에 secure라는 접미사를 사용하여 쿠키를 생성하면, 브라우저는 HTTPS가 아닌 통신에서는 쿠키를 전송하지 않는다.

 


미들웨어의 특성

 

req, res, next를 매개변수로 가지는 함수

app.use((req, res, next) =>{
 console.log('모든 요청 실행');
 next();
});

익스프레스 미들웨어들도 다음과 같이 축약이 가능하다.

순서가 중요하다 , static 미들웨어에서 파일을 찾는다면 next 호출을 안하므로 json, unlencoded, cookieParser는 실행되지 않는다.

app.use(
 morgan('dev'),
 express.static('/', path.join(__dirname, 'public')), //파일 찾을 경우 아래는 실행 안함
 express.json(),
 express.urlencoded({ extended: false }),
 cookieParser(process.env.COOKIE_SECRET),
);

next

next를 호출 해야 다음 코드로 넘어가는 역할

- next를 주석처리한다면 응답이 전송되지 않는다.

- 다음 미들웨어(라우터 미들웨어)로 넘어가지 않기 때문

- next에 인수로 값을 넣으면 에러 핸들러로 넘어간다('route'인 경우 다음 라우터로)

next 동작 과정


미들웨어간에 데이터 전달

 

req , res 객체 안에 값을 넣어 데이터 전달 가능

app.set 과의 차이 : app.set은 서버 내내 유지 // req,res 는 요청 하나 동안만 유지

일반적으로 res.locals 객체를 데이터 전달용으로 많이 사용한다.

app.use((req, res, next)=>{
 res.locals.data = '데이터 넣기';
 next();
},(req,res,next) =>{
 console.log(res.locals.data); //데이터 받기
 next();
});

 

미들웨어 확장하기

아래 두 코드는 동일한 역할이다.

app.use(morgan('dev'));

app.use((req,res,next)=>{
 morgan('dev')(req,res,next);
});

// 활용 예제
app.use((req, res, next) =>{
 if(process.env.NODE_ENV === 'production') {
  morgan('combined')(req, res, next);
 }else{
  morgan('dev')(req,res,next);
 }
});

 

멀티파트 데이터 형식

form 태그의 enctype이 multipart/form-data 인 경우

- body-parser 로는 요청 본문 해석이 불가능.

- multer 패키지가 필요  ( npm i multer로 패키지 설치)

<form id="form" action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="image1" />
    <input type="file" name="image2" />
    <input type="file" name="image3" />
    <input type="text" name="title" />
    <button type="submit">업로드</button>
 </form>

multer 설정하기

- storage는 저장할 공간에 대한 정보 (diskStorage)는 하드디스크에 업로드 파일을 저장 하겠다는것

- destination은 저장할 경로를 done의 두번째 인수로 넘기면 된다

- filename은 저장할 파일명(파일명 + 날짜 + 확장자)을 done으로 넘기면 된다

- limits는 파일 개수나 파일 사이즈를 제한할수 있다.

const multer = require('multer');

const upload = multer({
 storage: multer.diskStorage({
  destination(req, file, done) {
   done(null, 'uploads/');
  },
  filename(req, file, done) {
   const ext = path.extname(file.originalname);
   done(null, path.basename(file.originalname, ext) + Date.now() + ext); //같은 이름의 파일일 경우 시간으로 구별
  },
 }),
 limits:{ fileSize: 5 * 1024 * 1024 },
});

실제 서버를 운용할 때는 서버디스크 대신에 S3같은 스토리지 서비스에 저장하는것이 좋다. (storage 설정만 변경하면 된다)

 

multer 미들웨어들

single, none, array, fileds 미들웨어가 존재한다

- single은 하나의 파일을 업로드 할때, none은 파일을 아예 업로드 하지 않을때 사용

- req.file안에 업로드 정보를 저장

app.post('/upload', upload.single('image'), (req,res)=> {
 console.log(req.file, req.body);
 res.send('ok');
});

app.post('/upload', upload.none(), (req,res)=>{
 conosole.log(req.body);
 res.send('ok');
});

array 와 fileds는 여러개의 파일을 업로드할때 사용한다. (두 경우 모두 업로드 된 이미지 정보가 req.files 아래에 존재한다)

array는 하나의 요청 body 이름 아래 여러 파일이 있는 경우 사용

fields는 여러개의 요청 body 이름 아래 파일이 하나씩 있는 경우 

app.post('/upload', upload.array('many'), (req,res)=> {
 console.log(req.files, req.body);
 res.send('ok');
});

app.post('/upload', upload.fileds([{ name: 'image1'}, { name: 'image2'}] ), (req,res)=>{
 conosole.log(req.files, req.body);
 res.send('ok');
});

 

 

 

 

 

참조 : Node.js 교과서

'Node > Node.js교과서' 카테고리의 다른 글

[Node] sequelize  (0) 2023.05.22
[Node] express -3  (0) 2023.05.19
[Node] express -1  (0) 2023.05.04