express 템플릿을 정리하면서 사용된 기술에 대해서 한번 정리를 하고 진행할 예정이다

loader 적용 모듈

expressLoader

morgan

요청과 응답에 대한 정보를 콘솔에 기록

morgan(format, options)

morgan 로거 미들웨어 함수는 주어진 format, options을 이용하여 생성한다.
format은 미리 정의된 이름의 문자열(아래 참조), 형식 문자열, 또는 로그 항목을 생성하는 함수가 될 수 있다.
출처: https://inpa.tistory.com/entry/EXPRESS-📚-morgan-미들웨어 [Inpa Dev 👨‍💻:티스토리]
https://inpa.tistory.com/entry/EXPRESS-%F0%9F%93%9A-morgan-%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4

  • combined
  • common
    배포환경에서 사용
    불특정 다수가 접속하기 때문에 IP를 로그에 남겨줌
:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"
:remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length]
  • dev
    개발용을 위해 response에 따라 색상이 입혀진 축약된 로그를 출력.
    :status값이 빨간색이면 서버 에러코드, 노란색이면 클라이언트 에러 코드, 청록색은 리다이렉션 코드, 그외 코드는 컬러가 없다.
:method :url :status :response-time ms - :res[content-length]
  • short
    기본 설정보다 짧은 로그를 출력하고, 응답 시간을 포함.
:remote-addr :remote-user :method :url HTTP/:http-version :status :res[content-length] - :response-time ms
  • tiny
    최소화된 로그를 출력
:method :url :status :res[content-length] - :response-time ms
  • immediate
    response대신 request에 따라 로그를 작성한다. 
    서버 크래시가 발생하여도 request들은 기록되지만, reponse(response code, 컨텐츠 길이 등등)의 데이터는 기록할 수 없기 때문에 사용한다

  • skip

로깅의 스킵여부를 결정하기 위한 함수이다.
기본값은 false. 이 함수는 "skip(req, res)" 형식으로 호출된다.

:method :url :status :res[content-length] - :response-time ms

helmet

다양한 HTTP 헤더를 자동 설정을 통해 서버 어플리케이션의 보안을 강화해주는 NodeJS 보안 모듈
Express 기반 백엔드 서버에서 여러 Response header 보안 관련해서 설정해주는 미들웨어 함수의 모음인 것이다.

그래서 이 미들웨어 header 설정 함수만 공부하고 마스터해도 HTTP 보안 관련해서 어느 정도 공부가 될 것이다.


// helmet 기본 설정 사용. default 설정시 사용.
app.use(helmet());

// helmet 특정 기능만 사용할 때 사용
app.use(helmet.contentSecurityPolicy());
app.use(helmet.crossOriginEmbedderPolicy());
app.use(helmet.crossOriginOpenerPolicy());
app.use(helmet.crossOriginResourcePolicy());
app.use(helmet.dnsPrefetchControl()); // default 설정
app.use(helmet.expectCt());
app.use(helmet.frameguard()); // default 설정
app.use(helmet.hidePoweredBy()); // default 설정
app.use(helmet.hsts()); // default 설정
app.use(helmet.ieNoOpen()); // default 설정
app.use(helmet.noSniff()); // default 설정
app.use(helmet.originAgentCluster());
app.use(helmet.permittedCrossDomainPolicies());
app.use(helmet.referrerPolicy());
app.use(helmet.xssFilter()); // default 설정
// helmet() 이렇게만 사용하여 default 값으로만 사용할 경우, 적용되는 default 값은 아래와 같다.
Content-Security-Policy: default-src 'self';base-uri 'self';font-src 'self' https: data:;form-action 'self';frame-ancestors 'self';img-src 'self' data:;object-src 'none';script-src 'self';script-src-attr 'none';style-src 'self' https: 'unsafe-inline';upgrade-insecure-requests
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Origin-Agent-Cluster: ?1
Referrer-Policy: no-referrer
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Content-Type-Options: nosniff
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-XSS-Protection: 0
const cspOptions = {
  directives: {
    // 헬멧 기본 옵션 가져오기
    ...helmet.contentSecurityPolicy.getDefaultDirectives(), // 기본 헬멧 설정 객체를 리턴하는 함수를 받아 전개 연산자로 삽입
    
    /* 
    none : 어떳 것도 허용하지 않음
	self : 현재 출처에서는 허용하지만 하위 도메인에서는 허용되지 않음
	unsafe-inline : 인라인 자바스크립트, 인라인 스타일을 허용
	unsafe-eval	: eval과 같은 텍스트 자바스크립트 메커니즘을 허용 
    */
    // 구글 API 도메인과 인라인 스크립트, eval 스크립트를 허용
    "script-src": ["'self'", "*.googleapis.com", "'unsafe-inline'", "'unsafe-eval'"],
 
    // 다음과 카카오에서 이미지 소스를 허용
    'img-src': ["'self'", 'data:', '*.daumcdn.net', '*.kakaocdn.net'],
    
    // 소스에 https와 http 허용
    "base-uri" : ["/", "http:"],
  }
}
 
// Helmet의 모든 기능 사용. (contentSecurityPolicy에는 custom option 적용)
app.use(helmet({
  contentSecurityPolicy: cspOptions,
}));

https://www.lsevina126.asia/post/63366f2c7d98005032092cda

hpp

https://inpa.tistory.com/entry/NODE-%EB%B3%B4%EC%95%88-%F0%9F%93%9A-hpp-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%EB%B2%95
중복 이름 파라메터 공격을 방어해주는 모듈이다.
Express가 동일한 이름을 가진 파라메터들이 있을 경우 Array로 만들어주는데, 이때 의도치 않은 동작을 하도록 외부에서 공격할 수 있는 보안 문제가 될 수 있기 때문이다. (입력 데이터 검증을 회피하거나 앱 크래시를 유발)

flash

https://backback.tistory.com/340
https://not-to-be-reset.tistory.com/299
[ 상대적으로 중요도가 떨어지는 미들웨어 ]이다.
하지만 일회성 메시지들을 웹 브라우저에 나타낼때 좋다.

  • cors
    https://surprisecomputer.tistory.com/32
    CORS란 자신이 속하지 않은 다른 도메인, 다른 프로토콜, 혹은 다른 포트에 있는 리소스를 요청하는 cross-origin HTTP 요청 방식

    중요한 점은 서버는 기본적으로 CORS 방식을 제한해둔다. 즉, 사용하지 못하게 한다. 왜냐 하면, 특정 서버 리소스에 다른 임의의 웹 사이트들이 request를 보낼 수 있다면 악의적으로 특정 서버의 세션을 탈취하거나 서버에 무리가 가는 행위 등 문제가 생길 수 있는 행위를 할 수 있기 때문

express-session

https://kong-dev.tistory.com/133
https://kong-dev.tistory.com/134
앞서 설명했던 쿠키는 웹 브라우저에 저장되는 '키-밸류' 타입의 데이터라고 언급했습니다. 따라서 누구나 키에 따른 밸류를 확인할 수 있으므로 비밀정보를 쿠키로 보낸다면 비밀 정보를 아주 쉽게 탈취당할 수 있습니다.

세션은 이러한 문제점을 고려해서, 쿠키를 업그레이드 한 것이라 보면 됩니다. 쿠키와 달리 서버에 데이터를 저장하고 웹 브라우저는 Session ID만을 가지고 있기 때문에 비교적 안전합니다.

  1. 서버는 웹 브라우저에게 세션 값을 보냄 (sid 라고 하며, 아무런 의미도 없는 단순 식별자입니다.)

  2. 클라이언트는 접속할 때 자신이 가지고 있는 sid를 서버에게 전달

  3. 서버는 클라이언트가 보내준 sid를 가지고, 해당 유저를 식별

환경 변수 세팅

dotenv

https://80000coding.oopy.io/8262d415-2f2d-49a0-9a10-57bf545abfd4
환경변수를 관리할 수 있는 기초적인 툴 중 하나

보안 인증 관련

jsonwebtoken

https://kagrin97-blog.vercel.app/backend/jsonwebtoken

passport

Passport는 이름 그대로 서비스를 사용할 수 있게끔 해주는 여권 같은 역할을 하는 모듈이다.
회원가입과 로그인은 직접 구현할 수도 있지만, 세션과 쿠키 처리 등 복잡한 작업이 많으므로 검증된 모듈을 사용하는 것이 좋다.
그런 방면에서, Passport는 사용하기 좋은 검증된 모듈
클라이언트가 서버에 요청할 자격이 있는지 인증할 때에 passport 미들웨어를 사용하는 것

passport-jwt

passport-local

https://inpa.tistory.com/entry/NODE-%F0%9F%93%9A-Passport-%EB%AA%A8%EB%93%88-%EA%B7%B8%EB%A6%BC%EC%9C%BC%EB%A1%9C-%EC%B2%98%EB%A6%AC%EA%B3%BC%EC%A0%95-%F0%9F%92%AF-%EC%9D%B4%ED%95%B4%ED%95%98%EC%9E%90

strategy(전략)에 따른 요청으로 인증하기 위한 목적으로 사용
strategy 종류 (로그인 인증 방식) :

Local Strategy(passport-local) : 로컬 DB에서 로그인 인증 방식
Social Authentication (passport-kakao, passport-twitter 등) : 소셜 네트워크 로그인 인증 방식

API 동작 : 사용자가 passport에 인증 요청 -> passport는 인증 성공/실패시 어떤 제어를 할지 결정

profile
꾸준히 발전하는 풀스택 개발자!!

0개의 댓글