CS전공지식(프록시패턴,CORS)

박정호·2022년 7월 1일
0

CS

목록 보기
2/18
post-thumbnail

프록시 패턴

  • 프록시 패턴은 대상 객체에 접근하기 전 그 접근에 대한 흐름을 가로채 대상 객체 앞단의 인터페이스 역할을 하는 디자인패턴
  • 이를 통해 객체의 속성, 변환 등을 보완하며 보안, 데이터 검증, 캐싱, 로깅에 사용
  • proxy: 대리, 대리인
  • 프록시 객체와 프록시 서버로 활용


예시

용량이 큰 이미지와 글이 같이 있는 문서를 화면에 띄운다고 가정했을때, 텍스트는 용량이 작아서 빠르게 나타나지만 이미지는 용량이 크기 때문에 느리게 로딩되는 것을 확인할 수 있다. 만약 이렇게 처리되지 않고 텍스트와 이미지 로딩이 모두 끝난 후 화면이 나온다면 사용자는 로딩이 끝날때까지 기다려야 한다.
따라서, 로딩이 먼저 끝난 텍스트를 먼저 나오게 하는 것이 좋다. 이와 같은 방식을 가지려면 텍스트 처리용 프로세스, 이미지 처리용 프로세스를 별도로 운영하면 될 것이다.

장점

  • 전처리, 후처리 사용이 용이하다. (B가 C에게 요청하기 전 다른 작업을 전처리로 가능하다)
  • 특정 메서드에 대한 보안이 좋다. (B가 C에게 요청을 하여 A는 C가 무슨 일이 일어나는지 정확히 알기 힘들다)
  • 사이즈가 큰 객에가 로딩되기 전에 프록시를 통해 참조 가능

단점

  • 가독성이 떨어진다.
  • 객체 생성 시 한 단계를 거치는 과정이므로, 빈번한 객체 생성이 필요한 경우 성능이 저하 될 수 있다.

프록시 객체

어떠한 대상의 기본적인 동작(속성 접근, 할당, 순회, 열거, 함수 호출 등)의 작업을 가로챌 수 있는 객체를 뜻하며, 자바스크립트에서는 프록시 객체는 두개의 매개변수를 가진다.

  • target: 프록시할 대상
  • handler: 프록시 객체의 target동작을 가로채서 정의할 동작들이 정해져 있는 함수

ex)

const handler = {
    get: function(target, name) { 
        return name === 'name' ? `${target.a} ${target.b}` : target[name]
    }
}
const p = new Proxy({a: 'KUNDOL', b: 'IS AUMUMU ZANGIN'}, handler)
console.log(p.name) // KUNDOL IS AUMUMU ZANGIN

설명) new Proxy로 선언한 객체의 a와b라는 속성에 특정 문자열을 담아서 handler에 'name이라는 속성에 접근할 때는 a와 b라는 것을 합쳐서 문자열을 만들게 구현하였다. p라는 변수에 name이라는 속성을 선언하지 않았는데도 p.name으로 name 속성 접근하려 할 때 그부분을 가로채 문자열을 만들어 반환하는 것을 볼 수 있다.

프록시 서버

프록시서버는 서버와 클라이언트 사이에서 클라이언트가 자신을 통해 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템이나 응용프로그램을 가리킨다.

  • 프록시서버에서의 캐싱: 캐시 안에 정보를 담아두고, 캐시 안에 있는 정보를 요구하는 요청에 대해 다시 저 멀리 있는 원격 서버에 요청하지 않고 개시 안에 있는 데이터를 활용하는 것. 이를 통해 불필요하게 외부와 연결하지 않기 때문에 트래픽을 줄일 수 있다는 장점이 있다.

참고

프록시 서버로 쓰이는 nginx

  • 비동기 이벤트 기반의 구조와 다수의 연결을 효과적으로 처리 가능한 웹 서버이며, 주로 Node.js 서버 앞단의 프록시 서버로 활용
  • nginx를 프록시 서버로 둬서 실제 포트를 숨길 수 있고 정적 자원을 gzip압축하거나, 메인 서버 앞단에서의 로깅을 할 수 있다.

잠깐) 버퍼오버플로우

  • 버퍼 오버플로우: 버퍼는 데이터가 저장되는 메모리 공간으로, 메모리 공간을 벗어나는 경우를 말한다. 이때 사용되지 않아야 할 영역에 데이터가 덮어씌워져 주소, 값을 바꾸는 공격이 발생하기도 한다.

프록시 서버로 쓰는 CloudFlare

  • CDN 말고도 CloudFlare를 통해 누릴 수 있는 점이 많다. 대표적으로 DDOS방어, HTTPS 구축이 있다.
  • 사용자, 크롤러, 공격자가 자신의 웹 사이트에 접속하게 되는데, 이때 CloudFlare을 통해 공격자로부터 보호가 가능
  • 시스템을 통해 오는 트래픽을 차단해서 DDOS공격으로부터 보호
  • 별도의 인증서 설치 없이 좀 더 손쉽게 HTTPS 구축 가능

잠깐) CDN(Content Delivery Network)

  • 각 사용자가 인터넷에 접근하는 곳과 가까운 곳에서 콘텐츠를 캐싱 또는 배포하는 서버 네트워크를 말한다. 이를 통해 사용자가 웹 서버로부터 콘텐츠를 다운로드하는 시간일 줄어든다.

CORS와 프런트엔드의 프록시 서버

CORS

  • Cross-Origin Resource Sharing
  • 서버가 웹 브라우저에서 리소스를 로드할 때 다른 오리진을 통해 로드하지 못하게하는 HTTP 메커니즘
  • 즉, SOP를 지키기 위해서 나온 에러

프론트엔드 개발시 프론트엔드 서버를 만들어서 백엔드 서버와 통신할 때 주로 CORS 에러가 나는데, 이를 해결하기 위해 프론트엔드에서 프록시 서버를 만들기도 한다.

ex)
문제발생
프론트엔드에서는 127.0.0.1:3000으로 테스팅 , 백엔드 서버에서는 127.0.0.12010
-> 서로 포트번호가 다르기 때문에 CORS 에러 발생

해결방법 2가지

1. 프론트엔드에서 target 주소를 설정

  • 프록시 서버를 둬서 프론트엔드 서버에서 요청되는 오리진을 127.0.0.12010로 변경
axios.get("/stocks/days")
module.exports = {
	devServer:{
    	proxy:{
        '^/stocks':{
        	target:'http://127.0.0.1:12010'
            }
           }
          }
        }

2. 서버에서 CORS 설정

  • 운영환경에서 테스팅하려면 보통 cors + origin 설정
//ex) node express

const cors = require('cors')
app.use(cors())

잠깐) 오리진 & SOP

  • 오리진: 프로토콜과 호스트 이름, 포트의 조합을 말한다.
    https://houya.com:12010/test 라는 주소에서 오리진은 https://houya.com:12010 을 뜻.

  • SOP: Same Origin Policy라는 뜻, 같은 오리진끼리 로드한다는 의미

  • 상황: 사용자가 브라우저를 통해 네이버를 보는데, 네이버는 네이버의 서버에서 받아온 정보를 받아와서 화면단에 보이는 것. 만약 공격자가 하이재킹으로 서버의 정보를 빼내려한다면?
    -> 이를 방지하기 위해 같은 오리진끼리만 정보 전달이 되게 설정한 것(SOP)

Preflight request

  • option 메서드로 cors인지 한번 더 요청하는 것을 말한다.
  • put,delete와 같은 위험한 요청은 한번 더 브라우저가 확인 요청을 하는 것.
  • simple request 이외의 나머지는 preflight request이다.

simple request의 경우?

  • 메서드 : GET, HEAD, POST
  • Content-Type 헤더: application/x-www-form-urlendcoded, multipart/form-data, text/plain

참고: 민감한 인증 정보 같은 경우 Access-Control-Allow-Credentials 을 서버와 프론트엔드 모두 true로 설정하고, cors에 와일드카드를 넣은 쿠키나 인증헤더값은 민감함으로 에러가 발생

참고:https://min94programming.tistory.com/30
https://velog.io/@newtownboy/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%ED%94%84%EB%A1%9D%EC%8B%9C%ED%8C%A8%ED%84%B4Proxy-Pattern

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글