전단 크로스 필드 문제 (CORS)

13176 단어 httpcors전단
주로 브 라 우 저 CORS 의 크로스 도 메 인 을 정리 하고 다른 본인 은 , 예 를 들 어 iframe, window.name, window.postMessage 이 라 고 생각 합 니 다.
크로스 필드 정의
크로스 사이트 HTTP 요청 (Cross - site HTTP request) 은 요청 한 자원 이 있 는 도 메 인 이 이 요청 이 가리 키 는 자원 이 있 는 도 메 인 과 다른 HTTP 요청 을 말 합 니 다.
크로스 오 버 HTTP 가 정상적으로 요청 되 었 으 나 브 라 우 저 에 의 해 차단 되 었 습 니 다. 바로 입 니 다. 브 라 우 저 에 만 나타 나 고 자바 script 등 스 크 립 트 의 능 동적 http 요청 이 나타 납 니 다 .백 엔 드 에서 http 데 이 터 를 가 져 오 는 데 크로스 필드 문제 가 없습니다. 브 라 우 저 만 의 것 이 라 고 할 수 있 습 니 다 (또는 http 클 라 이언 트 만 의 것 이 라 고 할 수 있 습 니 다. 이것 은 사실 제정 자가 협 의 를 따 르 는 지 여부 에 달 려 있 습 니 다).
메모: 일부 브 라 우 저 는 HTTPS 의 도 메 인 에서 HTTP 에 접근 하 는 것 을 허용 하지 않 습 니 다. 예 를 들 어 Chrome 과 Firefox 등 브 라 우 저 는 요청 이 아직 발송 되 지 않 았 을 때 요청 을 차단 합 니 다. 이것 은 특례 입 니 다.
어떻게 해야만 크로스 필드 라 고 할 수 있 습 니까?
그럼 저 는 먼저 무엇 을 이해 해 야 합 니까?
두 페이지 의 프로 토 콜, 포트 (지정 되 어 있 으 면) 와 도 메 인 이름 이 같 으 면 두 페이지 는 같은 것 을 가지 고 있 습 니 다.
근원
다른 근원 은 바로 도 메 인 을 뛰 어 넘 는 것 이다.
다음 표 는 상대 적 으로 도 메 인 검 측 에 대한 예 시 를 보 여 주 었 다.
링크
크로스 오 버 여부
원인.http://store.company.com/dir/page.html
아니.http://store.company.com/dir2/other.html
아니.http://store.company.com/dir/inner/another.html
예.
서로 다른 프로 토 콜 (https 와 http)https://store.company.com/secure.html
예.
서로 다른 포트 (81 과 80)http://store.company.com:81/dir/etc.html
예.
다른 도 메 인 이름 (news 와 store)
도 메 인 을 뛰 어 넘 는 상황 은 다음 과 같다.
  • 서로 다른 프로 토 콜 (https 와 http)
  • 포트 별 (81 과 80)
  • 서로 다른 도 메 인 이름 (news 와 store)
  • IE 는 조금 다 르 고 여유 가 있 을 수 있 지만 전단 호 환 은 http://news.company.com/dir/other.html 이 므 로 IE 를 신경 쓰 지 않 아 도 된다.
    왜 크로스 제한 이 있어 야 합 니까?
    같은 소스 정책 은 같은 소스 에서 불 러 온 문서 나 스 크 립 트 가 다른 소스 에서 온 자원 과 어떻게 상호작용 하 는 지 제한 합 니 다.이것 은 잠재 적 인 악성 파일 을 격 리 하 는 데 사용 되 는 중요 한 보안 메커니즘 이다.
    아니면 안전 문제 입 니까? 제한 하지 않 으 면 (Cross - site request forgery, 중국어 이름: 크로스 오 버 요청 위조) 공격 이 쉽게 이 루어 집 니 다.
    예 를 들 어 크로스 제한 이 없다 고 가정 합 니 다.
    만약 에 당신 이 CSRF 사이트 의 관리자 라 고 가정 하면 a.com 사이트 에서 사용 자 를 삭제 할 수 있 는 권한 이 있 습 니 다. 예 를 들 어 이 과정 은 당신 의 신분 으로 로그 인하 고 POST 데 이 터 를 a.com 까지 만 하면 삭제 작업 을 할 수 있 습 니 다.그리고 만약 에 http://a.com/deleteUser 사이트 가 공격 을 당 했다 고 가정 하면 다른 사람 이 악성 코드 를 심 었 습 니 다. 당신 이 클릭 하면 크로스 도 메 인 요청 (브 라 우 저 에서 서로 다른 태그 로 b.coma.com 사 이 트 를 열 었 고 b.com 에 로그 인 했 습 니 다. 그러면 a.com 악성 코드 는 b.com 에 대한 크로스 도 메 인 요청 을 모 의 할 수 있 습 니 다.사용자 삭제 작업 을 모 의 하 는 것 은 간단 하 다.
    예 를 들 어 얼마나 위험한 일 인지 알 수 있 기 때문에 브 라 우 저 는 도 메 인 제한 을 합 니 다.
    사전 요청 이 무엇 입 니까?a.com 바로 사용 방법 이다.크로스 도 메 인 요청 은 우선 발송 OPTIONS, 즉 사용     서버 가 실제 요청 을 허용 하 는 지 알 수 있 도록 OPTIONS 서버 에 시작 합 니 다. 의 사용 은 크로스 도 메 인 요청 이 서버 의 사용자 데이터 에 예상 치 못 한 영향 을 미 치 는 것 을 피 할 수 있 습 니 다.
    도 메 인 을 넘 어야 사전 요청 이 있 지만 모든 도 메 인 요청 이 사전 요청 을 보 내 는 것 은 아 닙 니 다. 서버 가 정상적으로 돌아 오고 브 라 우 저 는 합 법 적 인지 판단 해 야 정상적으로 요청 할 수 있 습 니 다.따라서 웹 서비스 프로그램 은 options 를 처리 해 야 합 니 다. 그렇지 않 으 면 의 요청 도 백 엔 드 코드 를 실행 할 것 입 니 다.보통 OPTIONS (NO - Content) 로 돌아 가 는 것 이 좋다.
    구 글 개발 자 도구 에서 네트워크 요청 을 볼 때 204 이 분류 에 없 으 면 XHR 분류 나 Other 에서 볼 수 있다.
    언제 사전 요청 이 있 습 니까?
    일반 서버 에 서 는 기본적으로 요청 ALL 을 허용 하기 때문에 이 요청 들 은 전단 스 크 립 트 에 요청 헤드 를 추가 하지 않 으 면 미리 요청 하지 않 습 니 다.이 요청 들 은 GET、POST、HEAD 이 라 고 합 니 다.
    GET, POST, HEAD 만 사전 요청 이 없 을 수 있다 고 간단하게 요약 할 수 있다.
    대부분의 브 라 우 저 는 에 대한 을 지원 하지 않 습 니 다.만약 이 발생 하면 브 라 우 저 는 오 류 를 보고 합 니 다.
    The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

    간단하게 javascript 코드 예 를 들 어 보 겠 습 니 다:
    사전 요청 이 있 습 니 다:
    fetch('http://localhost:3000/demo-01', {
      method: 'get',
      headers: {
        //                。
        'Cache-Control': 'no-cache',
        Pragma: 'no-cache'
      },
    })

    사전 요청 없 음:
    fetch('http://localhost:3000/demo-01', {
      method: 'get'
    })

    크로스 도 메 인 플 로 차 트
    프로 세 스 도 는 프 록 시 서버 를 고려 하지 않 고 이상 상태 코드 를 고려 하지 않 습 니 다.前端跨域问题(CORS)_第1张图片
    몇몇 명칭 설명
  • 이름 이 다르다.
  • HTTP
  • HTTP HTTP
  • 크로스 도 메 인 솔 루 션
    알다 시 피 보안 을 위해 브 라 우 저 는 스 크 립 트 에서 시작 하 는 크로스 오 버 요청 을 제한 합 니 다.그러나 더욱 강력 하고 풍부 하 며 안전 한 웹 응용 프로그램 을 개발 하기 위해 개발 자 들 은 안전 을 잃 지 않 는 전제 에서 웹 응용 기술 이 점점 강해 지고 풍부 해 지 기 를 갈망한다.
    웹 응용 작업 그룹 (Web Applications Working Group) 은 크로스 소스 자원 공유 (Cross - Origin Resource Sharing (CORS)) 를 추천 했다.
    크로스 도 메 인 자원 공유 기준 이 한 그룹 추가 되 었 습 니 다. HTTP 첫 번 째 필드 에서 서버 가 어떤 소스 에 접근 할 수 있 는 권한 이 있 는 지 설명 할 수 있 습 니 다.
    도 메 인 간 설정 할 HTTP 첫 번 째 필드
    앞 뒤 단 크로스 도 메 인 요청 을 실현 하려 면 아래 와 관련 된 HTTP 을 설정 해 야 합 니 다.
    필드 이름
    설정 여부
    Access-Control-Allow-Origin
    예.
    Access-Control-Allow-Credentials
    아니.
    Access-Control-Allow-Methods
    아니.
    Access-Control-Max-Age
    아니.
    일반적으로 설정 HTTP 만 하면 도 메 인 을 넘 을 수 있 고 다른 필드 는 모두 배합 하여 사용 합 니 다 (다른 필드 는 기본 값 이 있 습 니 다).
    Access-Control-Allow-Origin
    크로스 필드 허용 은 이 필드 에서 설정 한 것 입 니 다. 기본적으로 설정 하지 않 을 때 크로스 필드 를 허용 하지 않 습 니 다.
    Access-Control-Allow-Origin:  | *

    origin 매개 변 수 는 이 서버 에 요청 할 수 있 는 URI 를 지정 합 니 다. credentials (즉 쿠키) 가 없 는 요청 에 대해 서 는 '*' 로 지정 하여 모든 도 메 인 에서 요청 할 수 있 음 을 표시 합 니 다.좀 더 안전 한 곳 을 원한 다 면 당연히 URI 를 지정 할 수도 있다.
    예시
    Access-Control-Allow-Origin: *
    Access-Control-Allow-Origin: http://foo.example

    Access-Control-Allow-Credentials
    이 필드 는 쿠키 를 전송 할 수 있 는 지 여 부 를 설정 하 는 데 사 용 됩 니 다. 기본 값 은 false 입 니 다.
    Access-Control-Allow-Credentials: true | false

    Access-Control-Allow-Methods
    기본 값 은 보통 Access-Control-Allow-Origin 이 므 로 delete 등 방법 을 사용 할 때 기본 값 이 제 한 됩 니 다.
    Access-Control-Allow-Methods: [, ]*

    자원 이 요청 할 수 있 는 방식 이 어떤 것 이 있 는 지 알려 줍 니 다.이 응답 헤더 정 보 는 클 라 이언 트 가 예비 검사 요청 을 할 때 반 환 됩 니 다.그 건 필요 하 니까.GET、HEAD、POST 로 설정 되 었 을 때 모든 방식 을 포함 하지 않 았 습 니 다. 예 를 들 어 patch 는 모든 방식 으로 설정 하 는 것 이 더 안전 합 니 다.
    예:
    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Methods: *
    Access-Control-Allow-Methods: GET

    Access-Control-Allow-Headers
    브 라 우 저 자체 에 첨부 된 요청 헤드 는 기본적으로 허용 되 지만 전단 코드 에 추 가 된 요청 헤드 는 도 메 인 을 넘 을 때 허용 되 어야 접근 할 수 있 습 니 다.
    또한 브 라 우 저 자체 의 기본 테이프 * 는 수정 할 수 없습니다. 예 를 들 어 , User-Agent 등 입 니 다.
    Access-Control-Allow-Headers: [, ]*

    예:
    Access-Control-Allow-Headers: Pragma,Cache-Control
    Access-Control-Allow-Headers: *
    Access-Control-Allow-Methods: Pragma

    Access-Control-Max-Age
    Access-Control-Max-Age: 

    이것 Origin 은 이번 결과 의 유효기간 이 얼마나 되 는 지 알려 주 고 유효기간 내 요청 은 사용 하지 않 아 도 된다 .
    크로스 오 버 실천
    구 글 에서 전단 코드 를 방문 하고 실행 하 십시오. IE 도 메 인 이름 이 같은 포트 와 달리 도 메 인 문 제 는 존재 하지 않 습 니 다.
    node express 서비스 인 스 턴 스
    const express = require('express');
    const app = express();
    
    //begin----          
    app.disable('etag');
    app.use(function(req, res, next) {
      //                  
      res.header('Cache-Control', 'no-store');
      //  http1.0
      res.header('Pragma', 'no-cache');
      next();
    });
    //end----          
    
    //all,          ,         。
    app.all('/demo-normal', function(req, res) {
      res.header('Access-Control-Allow-Origin', '*');
      res.send('Hello World!');
    });
    
    app.all('/demo-allow-method', function(req, res) {
      res.header('Access-Control-Allow-Origin', '*');
      //    delete    ,   get      
      res.header('Access-Control-Allow-Methods', 'DELETE');
      res.send('Hello World!');
    });
    
    app.all('/demo-credentials-cannot-work', function(req, res) {
      res.header('Access-Control-Allow-Origin', '*');
      //        ,  Access-Control-Allow-Origin * ,      
      //      cookie,      
      //             cookie ,      cookie   
      res.header('Access-Control-Allow-Credentials', 'true');
      res.send('Hello World!');
    });
    app.all('/demo-credentials-can-work', function(req, res) {
      //       ,                ,        。
      //      cookie,      
      //             cookie ,      cookie   
      res.header('Access-Control-Allow-Origin', req.headers.origin);
      res.header('Access-Control-Allow-Credentials', 'true');
      res.send('Hello World!');
    });
    
    app.all('/demo-max-age', function(req, res) {
      res.header('Access-Control-Allow-Origin', '*');
      //      30 
      res.header('Access-Control-Max-Age', 30);
      //delete       
      res.header('Access-Control-Allow-Methods', 'DELETE');
      if (req.method === 'OPTIONS') {
        //         ,               。
        //       204,NO-Content(   )
        res.status(204).send('');
        return;
      }
      res.send('Hello World!');
    });
    
    app.listen(3000, () => console.log('Demo listening on port 3000!'));

    전단 인 스 턴 스
    우선 위의 node 서 비 스 를 시작 하고 아래 명령 을 실행 해 야 합 니 다.
    mkdir cors-node-server
    cd cors-node-server
    npm init #   npm  
    npm i express #  express
    touch index.js #    ,      node express       index.js
    node ./index.js
    #        

    그리고 아래 코드 는 브 라 우 저 콘 솔 에 직접 복사 하여 실행 한 다음 네트워크 요청 을 볼 수 있 습 니 다.그러나 쿠키 와 관련 된 경우 html 파일 을 직접 방문 해 야 쿠키 를 추가 할 수 있 습 니 다.
    현재 express 에서 실행 하지 마 세 요. 그렇지 않 으 면 당연히 크로스 필드 문제 가 없 을 것 입 니 다.
    청구 1
    fetch('http://localhost:3000/demo-normal', {
      method: 'GET',
    })

    method 는 모두 정상적으로 접근 하지만 GET、POST、HEAD 등 을 사용 하면 접근 에 실패 합 니 다.그리고 DELETE、PUT、PATCH 미리 요청 하지 않 았 지만 GET、POST、HEAD 바로 DELETE、PUT、PATCH 구 글 콘 솔 은 다음 과 같은 정 보 를 되 돌려 주 었 다.
    Failed to load http://localhost:3000/demo-normal: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

    청구 2
    fetch('http://localhost:3000/demo-allow-method', {
      method: 'DELETE'
    })

    방문 method 는 사전 요청 이 있 을 수 있 으 며 정상 적 인 귀환 을 요청 합 니 다.다른 것 은 요청 한 예 와 일치 합 니 다.
    요청 3 (쿠키 추가)
    fetch('http://localhost:3000/demo-credentials-cannot-work', {
      method: 'GET',
      credentials: 'include'
    })

    접근 에 실 패 했 습 니 다. 오 류 를 다음 과 같이 되 돌려 줍 니 다.
    Failed to load http://localhost:3000/demo-credentials-cannot-work: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'https://developer.mozilla.org' is therefore not allowed access.
    delete 이 true 로 설정 되 었 을 때 Access-Control-Allow-CredentialsAccess-Control-Allow-Origin 이 될 수 없고 구체 적 으로 접근 할 도 메 인 이름 출처 를 지정 해 야 한 다 는 뜻 이다.
    요청 4 (쿠키 추가)
    우선 현재 도 메 인 이름 에 쿠키 를 추가 해 야 합 니 다.
    fetch('http://localhost:3000/demo-credentials-can-work', {
      method: 'GET',
      credentials: 'include'
    })

    정상적으로 접근 한 다음 요청 헤더 에서 * 필드 를 볼 수 있 습 니 다. 물론 전 제 는 localhost 이 도 메 인 이름 에 쿠키 가 있다 는 것 입 니 다.
    Accept: */*
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    Connection: keep-alive
    Cookie: test=123
    Host: localhost:3000
    Origin: https://developer.mozilla.org
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36

    요청 5 (사전 요청 유효기간)
    fetch('http://localhost:3000/demo-max-age', {
      method: 'DELETE'
    })

    우선 첫 번 째 요청 은 Cookie 있 고 30 초 유효기간 내 에 다시 요청 합 니 다 localhost.그리고 이 유효기간 은 계속 순환 할 것 이다.
    참고 문장
  • 브 라 우 저의 동원 정책
  • HTTP 접근 제어
  • 좋은 웹페이지 즐겨찾기