웹 프론트엔드 JS 튜토리얼 CORS 교차 도메인 요청에서 다중 도메인 이름 화이트리스트를 설정하기 위한 Node.js의 샘플 코드 공유

CORS 교차 도메인 요청에서 다중 도메인 이름 화이트리스트를 설정하기 위한 Node.js의 샘플 코드 공유

Mar 28, 2017 pm 02:34 PM

이 글에서는 주로 Node.js CORS 크로스 도메인 요청에서 다중 도메인 이름 화이트리스트를 설정하는 방법을 샘플 코드를 통해 자세히 소개하고 있습니다. 그것은 모든 사람에게 유용할 것이라고 믿습니다. 필요한 친구는 아래를 살펴볼 수 있습니다.

CORS

CORS라고 하면 프론트엔드는 다들 잘 아실 거라 생각해서 여기서는 자세히 설명하지 않겠습니다. 자세한 내용은 이 기사를 읽어보세요.

CORS는 주로 인터페이스 액세스를 허용하는 도메인 이름에 대한 응답 헤더의 Access-Control-Allow-Origin 속성을 구성합니다. 가장 일반적인 설정은

res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true'); // 允许服务器端发送Cookie数据
로그인 후 복사

입니다. 그러나 이 설정은 가장 단순하고 조야하며 가장 안전하지도 않습니다. 이는 인터페이스가 모든 도메인 이름이 도메인 간 요청을 할 수 있도록 허용한다는 의미입니다. 그러나 일반적인 실제 비즈니스에서는 인터페이스가 전체가 아닌 하나 또는 소수의 웹사이트에만 도메인 간 요청 권한을 허용하는 것으로 예상됩니다.

그래서 똑똑한 분들은 여러 도메인 이름을 화이트리스트에 추가하는 것이 쉽지 않을까요? 그냥 일반적인 규칙만 작성하면 된다고 생각하실 것입니다. 그래도 작동하지 않으면 Access-Control-Allow-Origin 속성을 쉼표로 구분된 여러 도메인 이름에 직접 구성하는 것이 더 좋지 않을까요?

이렇게:

아아아아

이러한 글쓰기 방식은 유효하지 않다는 점을 말씀드리게 되어 죄송합니다. Node.js에서는 res 응답 헤더의 Access-Control-Allow-Origin 속성이 (*) 이외의 정규식과 일치할 수 없으며 도메인 이름을 쉼표로 구분할 수 없습니다. 즉, Access-Control-Allow-Origin의 속성 값은 단일 특정 도메인 이름 문자열 또는 (*)에만 설정되도록 허용됩니다.

여러 도메인 이름을 허용하고 안전하지 않은 * 와일드카드 를 사용하고 싶지 않기 때문에 여러 도메인 이름 화이트리스트에 대해 CORS를 구성할 수 없다는 것이 사실입니까?

여러 도메인 이름 화이트리스트가 있는 CORS는 실제로 달성 가능합니다. 나라를 구하기 위한 약간의 반전이 있을 뿐입니다.

다중 도메인 화이트리스트의 CORS 구현 원칙

구체적인 원칙은 cors 라이브러리의 핵심 코드를 참조하세요.

res.header('Access-Control-Allow-Origin', '*.666.com'); 

// 或者如下
res.header('Access-Control-Allow-Origin', 'a.666.com,b.666.com,c.666.com');
로그인 후 복사

구현 원칙은 다음과 같습니다.

Access-Control-Allow-Origin 속성에서 여러 도메인 이름을 설정할 수 없음을 분명히 하였으므로, 우리는 이 길을 포기해야 합니다.

가장 널리 사용되고 효과적인 방법은 요청된 헤더의 Origin 속성 값(req.header.origin)이 도메인 이름 허용 목록에 있는지 서버 측에서 확인하는 것입니다. 화이트리스트에 있는 경우 Access-Control-Allow-Origin을 현재 Origin 값으로 설정합니다. 이는 Access-Control-Allow-Origin의 단일 도메인 이름 요구 사항을 충족하고 현재 요청이 있는 경우 액세스되도록 합니다. 화이트리스트에 없으면 오류 메시지가 반환됩니다.

이런 방식으로 교차 도메인 요청 확인을 브라우저에서 서버로 전송합니다. 원본 문자열 확인은 일반 문자열 확인과 동일하게 됩니다. 배열 목록 확인을 사용할 수 있을 뿐만 아니라 일반 일치도 사용할 수 있습니다.

구체 코드는 다음과 같습니다.

(function () {

 'use strict';

 var assign = require('object-assign');
 var vary = require('vary');

 var defaults = {
 origin: '*',
 methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
 preflightContinue: false,
 optionsSuccessStatus: 204
 };

 function isString(s) {
 return typeof s === 'string' || s instanceof String;
 }

 function isOriginAllowed(origin, allowedOrigin) {
 if (Array.isArray(allowedOrigin)) {
 for (var i = 0; i < allowedOrigin.length; ++i) {
 if (isOriginAllowed(origin, allowedOrigin[i])) {
  return true;
 }
 }
 return false;
 } else if (isString(allowedOrigin)) {
 return origin === allowedOrigin;
 } else if (allowedOrigin instanceof RegExp) {
 return allowedOrigin.test(origin);
 } else {
 return !!allowedOrigin;
 }
 }

 function configureOrigin(options, req) {
 var requestOrigin = req.headers.origin,
 headers = [],
 isAllowed;

 if (!options.origin || options.origin === &#39;*&#39;) {
 // allow any origin
 headers.push([{
 key: &#39;Access-Control-Allow-Origin&#39;,
 value: &#39;*&#39;
 }]);
 } else if (isString(options.origin)) {
 // fixed origin
 headers.push([{
 key: &#39;Access-Control-Allow-Origin&#39;,
 value: options.origin
 }]);
 headers.push([{
 key: &#39;Vary&#39;,
 value: &#39;Origin&#39;
 }]);
 } else {
 isAllowed = isOriginAllowed(requestOrigin, options.origin);
 // reflect origin
 headers.push([{
 key: &#39;Access-Control-Allow-Origin&#39;,
 value: isAllowed ? requestOrigin : false
 }]);
 headers.push([{
 key: &#39;Vary&#39;,
 value: &#39;Origin&#39;
 }]);
 }

 return headers;
 }

 function configureMethods(options) {
 var methods = options.methods;
 if (methods.join) {
 methods = options.methods.join(&#39;,&#39;); // .methods is an array, so turn it into a string
 }
 return {
 key: &#39;Access-Control-Allow-Methods&#39;,
 value: methods
 };
 }

 function configureCredentials(options) {
 if (options.credentials === true) {
 return {
 key: &#39;Access-Control-Allow-Credentials&#39;,
 value: &#39;true&#39;
 };
 }
 return null;
 }

 function configureAllowedHeaders(options, req) {
 var allowedHeaders = options.allowedHeaders || options.headers;
 var headers = [];

 if (!allowedHeaders) {
 allowedHeaders = req.headers[&#39;access-control-request-headers&#39;]; // .headers wasn&#39;t specified, so reflect the request headers
 headers.push([{
 key: &#39;Vary&#39;,
 value: &#39;Access-Control-Request-Headers&#39;
 }]);
 } else if (allowedHeaders.join) {
 allowedHeaders = allowedHeaders.join(&#39;,&#39;); // .headers is an array, so turn it into a string
 }
 if (allowedHeaders && allowedHeaders.length) {
 headers.push([{
 key: &#39;Access-Control-Allow-Headers&#39;,
 value: allowedHeaders
 }]);
 }

 return headers;
 }

 function configureExposedHeaders(options) {
 var headers = options.exposedHeaders;
 if (!headers) {
 return null;
 } else if (headers.join) {
 headers = headers.join(&#39;,&#39;); // .headers is an array, so turn it into a string
 }
 if (headers && headers.length) {
 return {
 key: &#39;Access-Control-Expose-Headers&#39;,
 value: headers
 };
 }
 return null;
 }

 function configureMaxAge(options) {
 var maxAge = options.maxAge && options.maxAge.toString();
 if (maxAge && maxAge.length) {
 return {
 key: &#39;Access-Control-Max-Age&#39;,
 value: maxAge
 };
 }
 return null;
 }

 function applyHeaders(headers, res) {
 for (var i = 0, n = headers.length; i < n; i++) {
 var header = headers[i];
 if (header) {
 if (Array.isArray(header)) {
  applyHeaders(header, res);
 } else if (header.key === &#39;Vary&#39; && header.value) {
  vary(res, header.value);
 } else if (header.value) {
  res.setHeader(header.key, header.value);
 }
 }
 }
 }

 function cors(options, req, res, next) {
 var headers = [],
 method = req.method && req.method.toUpperCase && req.method.toUpperCase();

 if (method === &#39;OPTIONS&#39;) {
 // preflight
 headers.push(configureOrigin(options, req));
 headers.push(configureCredentials(options, req));
 headers.push(configureMethods(options, req));
 headers.push(configureAllowedHeaders(options, req));
 headers.push(configureMaxAge(options, req));
 headers.push(configureExposedHeaders(options, req));
 applyHeaders(headers, res);

 if (options.preflightContinue ) {
 next();
 } else {
 res.statusCode = options.optionsSuccessStatus || defaults.optionsSuccessStatus;
 res.end();
 }
 } else {
 // actual response
 headers.push(configureOrigin(options, req));
 headers.push(configureCredentials(options, req));
 headers.push(configureExposedHeaders(options, req));
 applyHeaders(headers, res);
 next();
 }
 }

 function middlewareWrapper(o) {
 if (typeof o !== &#39;function&#39;) {
 o = assign({}, defaults, o);
 }

 // if options are static (either via defaults or custom options passed in), wrap in a function
 var optionsCallback = null;
 if (typeof o === &#39;function&#39;) {
 optionsCallback = o;
 } else {
 optionsCallback = function (req, cb) {
 cb(null, o);
 };
 }

 return function corsMiddleware(req, res, next) {
 optionsCallback(req, function (err, options) {
 if (err) {
  next(err);
 } else {
  var originCallback = null;
  if (options.origin && typeof options.origin === &#39;function&#39;) {
  originCallback = options.origin;
  } else if (options.origin) {
  originCallback = function (origin, cb) {
  cb(null, options.origin);
  };
  }

  if (originCallback) {
  originCallback(req.headers.origin, function (err2, origin) {
  if (err2 || !origin) {
  next(err2);
  } else {
  var corsOptions = Object.create(options);
  corsOptions.origin = origin;
  cors(corsOptions, req, res, next);
  }
  });
  } else {
  next();
  }
 }
 });
 };
 }

 // can pass either an options hash, an options delegate, or nothing
 module.exports = middlewareWrapper;

}());
로그인 후 복사

아 맞네요~

요약

위 내용은 CORS 교차 도메인 요청에서 다중 도메인 이름 화이트리스트를 설정하기 위한 Node.js의 샘플 코드 공유의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
1 몇 달 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

Node의 메모리 제어에 관한 기사 Node의 메모리 제어에 관한 기사 Apr 26, 2023 pm 05:37 PM

Non-Blocking, Event-Driven 기반으로 구축된 Node 서비스는 메모리 소모가 적다는 장점이 있으며, 대규모 네트워크 요청을 처리하는데 매우 적합합니다. 대규모 요청을 전제로 '메모리 제어'와 관련된 문제를 고려해야 합니다. 1. V8의 가비지 수집 메커니즘과 메모리 제한 Js는 가비지 수집 기계에 의해 제어됩니다.

Node V8 엔진의 메모리와 GC에 대한 자세한 그래픽 설명 Node V8 엔진의 메모리와 GC에 대한 자세한 그래픽 설명 Mar 29, 2023 pm 06:02 PM

이 기사는 NodeJS V8 엔진의 메모리 및 가비지 수집기(GC)에 대한 심층적인 이해를 제공할 것입니다. 도움이 되기를 바랍니다.

최고의 Node.js Docker 이미지를 선택하는 방법에 대해 이야기해 볼까요? 최고의 Node.js Docker 이미지를 선택하는 방법에 대해 이야기해 볼까요? Dec 13, 2022 pm 08:00 PM

Node용 Docker 이미지를 선택하는 것은 사소한 문제처럼 보일 수 있지만 이미지의 크기와 잠재적인 취약점은 CI/CD 프로세스와 보안에 상당한 영향을 미칠 수 있습니다. 그렇다면 최고의 Node.js Docker 이미지를 어떻게 선택합니까?

Node의 파일 모듈에 대해 자세히 이야기해 보겠습니다. Node의 파일 모듈에 대해 자세히 이야기해 보겠습니다. Apr 24, 2023 pm 05:49 PM

파일 모듈은 파일 읽기/쓰기/열기/닫기/삭제 추가 등과 같은 기본 파일 작업을 캡슐화한 것입니다. 파일 모듈의 가장 큰 특징은 모든 메소드가 **동기** 및 ** 두 가지 버전을 제공한다는 것입니다. 비동기**, sync 접미사가 있는 메서드는 모두 동기화 메서드이고, 없는 메서드는 모두 이기종 메서드입니다.

Node.js 19가 공식적으로 출시되었습니다. Node.js의 6가지 주요 기능에 대해 이야기해 보겠습니다! Node.js 19가 공식적으로 출시되었습니다. Node.js의 6가지 주요 기능에 대해 이야기해 보겠습니다! Nov 16, 2022 pm 08:34 PM

Node 19가 정식 출시되었습니다. 이 글에서는 Node.js 19의 6가지 주요 기능에 대해 자세히 설명하겠습니다. 도움이 되셨으면 좋겠습니다!

Node.js의 GC(가비지 수집) 메커니즘에 대해 이야기해 보겠습니다. Node.js의 GC(가비지 수집) 메커니즘에 대해 이야기해 보겠습니다. Nov 29, 2022 pm 08:44 PM

Node.js는 GC(가비지 수집)를 어떻게 수행하나요? 다음 기사에서는 이에 대해 설명합니다.

Node의 이벤트 루프에 대해 이야기해 봅시다. Node의 이벤트 루프에 대해 이야기해 봅시다. Apr 11, 2023 pm 07:08 PM

이벤트 루프는 Node.js의 기본 부분이며 메인 스레드가 차단되지 않도록 하여 비동기 프로그래밍을 가능하게 합니다. 이벤트 루프를 이해하는 것은 효율적인 애플리케이션을 구축하는 데 중요합니다. 다음 기사는 Node.js의 이벤트 루프에 대한 심층적인 이해를 제공할 것입니다. 도움이 되기를 바랍니다!

노드가 npm 명령을 사용할 수 없으면 어떻게 해야 합니까? 노드가 npm 명령을 사용할 수 없으면 어떻게 해야 합니까? Feb 08, 2023 am 10:09 AM

노드가 npm 명령을 사용할 수 없는 이유는 환경 변수가 올바르게 구성되지 않았기 때문입니다. 해결 방법은 다음과 같습니다. 1. "시스템 속성"을 엽니다. 2. "환경 변수" -> "시스템 변수"를 찾은 다음 환경을 편집합니다. 3. nodejs 폴더의 위치를 ​​찾습니다. 4. "확인"을 클릭합니다.

See all articles