source

Firebase를 위한 클라우드 기능에서의 CORS의 이니블화

nicesource 2023. 2. 6. 23:57
반응형

Firebase를 위한 클라우드 기능에서의 CORS의 이니블화

현재 Firebase에 새로운 Cloud Functions를 사용하는 방법을 배우고 있는데, 문제는 AJAX 요청을 통해 작성한 기능에 액세스할 수 없다는 것입니다."No 'Access-Control-Allow-Origin' 오류가 나타납니다.다음은 제가 작성한 함수의 예입니다.

exports.test = functions.https.onRequest((request, response) => {
  response.status(500).send({test: 'Testing functions'});
})

함수는 다음 URL에 있습니다.https://us-central1-fba-shipper-140ae.cloudfunctions.net/test

Firebase 문서에서는 CORS 미들웨어를 함수에 추가할 것을 제안하고 있습니다.시도해 봤지만 작동하지 않습니다.https://firebase.google.com/docs/functions/http-events

저는 이렇게 했습니다.

var cors = require('cors');    

exports.test = functions.https.onRequest((request, response) => {
   cors(request, response, () => {
     response.status(500).send({test: 'Testing functions'});
   })
})

내가 뭘 잘못하고 있지?이 건에 대해 어떤 도움이라도 주시면 감사하겠습니다.

갱신:

더그 스티븐슨의 대답이 도움이 되었다.({origin: true})를 추가하여 문제를 수정하고 수정해야 했습니다.response.status(500)로로 합니다.response.status(200)처음엔 완전히 놓쳤죠

Firebase 팀이 제공하는 두 가지 샘플 기능은 CORS 사용을 보여줍니다.

두 번째 샘플은 현재 사용하고 있는 것과는 다른 코르 작업 방식을 사용하고 있습니다.

샘플에 나타나듯이 다음과 같이 Import하는 것을 검토해 주십시오.

const cors = require('cors')({origin: true});

그리고 함수의 일반적인 형태는 다음과 같습니다.

exports.fn = functions.https.onRequest((req, res) => {
    cors(req, res, () => {
        // your function body here - use the provided req and res from cors
    })
});

클라우드에서 CORS를 이렇게 설정할 수 있습니다.

response.set('Access-Control-Allow-Origin', '*');

[ Import ]는 할 .cors

Typescript에서 이 작업을 수행하려는 사용자는 다음과 같이 하십시오.

import * as cors from 'cors';
const corsHandler = cors({origin: true});

export const exampleFunction= functions.https.onRequest(async (request, response) => {
       corsHandler(request, response, () => {});
       //Your code here
});

잠시 후 검색하실 분들을 위해 추가 정보 하나 드리겠습니다.파이어베이스 호스팅을 사용하는 경우 (firebase_hosting_host)/api/myfunctions_host)/doStuff 함수와 같은 URL이 리다이렉트되도록 개서를 설정할 수도 있습니다.이렇게 하면 리다이렉션은 투과적이고 서버측이기 때문에 코스에 대처할 필요가 없습니다.

파이어베이스에 리라이트 섹션으로 설정할 수 있습니다.json:

"rewrites": [
        { "source": "/api/myFunction", "function": "doStuff" }
]

나한테는 어떤 CORS 해결책도 통하지 않았어지금까지!

저와 같은 문제에 부딪힌 사람이 있는지 모르겠지만, 제가 발견한 예와 다른 5가지 방법으로 CORS를 설정했는데, 아무 것도 효과가 없는 것 같습니다.정말 버그인지 확인하기 위해 Plunker에서 최소한의 예시를 설정했지만 예시는 훌륭하게 실행되었습니다.Firebase 기능 로그(Firebase Console에 있는 것)를 확인하기로 했습니다.CORS 관련이 아닌 노드 서버 코드에 몇 가지 오류가 있어 디버깅CORS 오류 메시지가 해제되었습니다.CORS와 무관한 코드 에러가 왜 CORS 에러 응답을 반환하는지 모르겠습니다만, 그 때문에, 몇시간이나 잘못된 토끼굴로 빠져들었습니다.

tl;dr - CORS 솔루션이 작동하지 않는 경우 파이어베이스 기능 로그를 확인하고 오류가 있으면 디버깅합니다.

나는 @Andreys 자신의 질문에 대한 대답에 조금 더 덧붙이고 싶다.

것 .cors(req, res, cb)콜백에 모든 코드를 삽입하지 않고 기능 상단에 있는 코르스 모듈을 호출할 수 있습니다.나중에 코르스를 구현하려면 이 방법이 훨씬 빠릅니다.

exports.exampleFunction = functions.https.onRequest((request, response) => {
    cors(request, response, () => {});
    return response.send("Hello from Firebase!");
});

오프닝 포스트에 언급된 대로 코르스를 시작하는 것을 잊지 마십시오.

const cors = require('cors')({origin: true});

업데이트: 이 구현에는 적절한 비동기/대기 기능이 없기 때문에 시간이 걸리는 응답 기능은 CORS 오류의 위험이 있습니다.정적 데이터를 반환하는 빠른 프로토타이핑 끝점 밖에서 사용하지 마십시오.

갱신된 답변: 사용corsTypescript:

cors

npm i -S cors
npm i --save-dev @types/cors

index.ts:

import * as cors from "cors";
const corsHandler = cors({ origin: true });

// allow cors in http function
export const myFunction = functions.https.onRequest((req, res) => {
corsHandler(req, res, async () => {

// your method body

 });
});

(예: (예: (예:)
Cors를 할 수 . it, 도, it, 와, 와, 습, 습, 습, 습, 습, 습, it, it, it, itTypescript81.0으로 하다

exports.createOrder = functions.https.onRequest((req, res) => {
// browsers like chrome need these headers to be present in response if the api is called from other than its base domain
  res.set("Access-Control-Allow-Origin", "*"); // you can also whitelist a specific domain like "http://127.0.0.1:4000"
  res.set("Access-Control-Allow-Headers", "Content-Type");

  // your code starts here

  //send response
  res.status(200).send();
});

이게 도움이 될 수도 있어요.firebase HTTP 클라우드 기능을 express(커스텀 URL)로 만들었습니다.

const express = require('express');
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
const main = express();

app.post('/endpoint', (req, res) => {
    // code here
})

app.use(cors({ origin: true }));
main.use(cors({ origin: true }));
main.use('/api/v1', app);
main.use(bodyParser.json());
main.use(bodyParser.urlencoded({ extended: false }));

module.exports.functionName = functions.https.onRequest(main);

다시 쓰기 섹션을 추가했는지 확인하십시오.

"rewrites": [
      {
        "source": "/api/v1/**",
        "function": "functionName"
      }
]

Google 클라우드 콘솔 대시보드를 사용한 간단한 솔루션:

  1. GCP 콘솔 대시보드로 이동합니다.

https://console.cloud.google.com/home/dashboard

  1. 메뉴로 이동

"클라우드 기능"("컴퓨팅" 섹션)

  1. 클라우드 기능을 선택합니다(예: "MyFunction"). 오른쪽에 액세스 제어 설정을 보여주는 사이드 메뉴가 나타납니다.

  2. "구성원 추가"를 클릭하고 "allUsers"를 입력한 후 "Cloud Function Invoker" 역할을 선택합니다.

  3. 저장 -> 클라우드 기능 목록에 "인증되지 않음 허용"이라는 설명이 표시됩니다.

이제 GCP 또는 Firebase 프로젝트에 대한 올바른 설정을 가진 모든 사용자가 인터넷에서 액세스할 수 있게 되었습니다.(조심하세요)

플러그인을 않거나 수 없는 cors를 합니다.setCorsHeaders()핸들러 기능의 첫 번째 기능도 동작합니다.

응답할 때도 responseSuccess/Error 함수를 사용합니다.

const ALLOWED_ORIGINS = ["http://localhost:9090", "https://sub.example.com", "https://example.com"]


// Set CORS headers for preflight requests
function setCorsHeaders (req, res) {
  var originUrl = "http://localhost:9090"


  if(ALLOWED_ORIGINS.includes(req.headers.origin)){
    originUrl = req.headers.origin
  }

  res.set('Access-Control-Allow-Origin', originUrl);
  res.set('Access-Control-Allow-Credentials', 'true');

  if (req.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    res.set('Access-Control-Allow-Methods', 'GET,POST','PUT','DELETE');
    res.set('Access-Control-Allow-Headers', 'Bearer, Content-Type');
    res.set('Access-Control-Max-Age', '3600');
    res.status(204).send('');
  }
}

function respondError (message, error, code, res) {
  var response = {
    message: message,
    error: error
  }
  res.status(code).end(JSON.stringify(response));
}


function respondSuccess (result, res) {
  var response = {
    message: "OK",
    result: result
  }
  res.status(200).end(JSON.stringify(response));
}

나 같은 사람이 밖에 있다면:클라우드 함수와 동일한 프로젝트에서 클라우드 함수를 직접 호출하려면 Firebase sdk를 시작하고 onCall 메서드를 사용할 수 있습니다.모든 것을 처리할 수 있습니다.

exports.newRequest = functions.https.onCall((data, context) => {
    console.log(`This is the received data: ${data}.`);
    return data;
})

이 함수를 다음과 같이 호출합니다.

// Init the firebase SDK first    
const functions = firebase.functions();
const addMessage = functions.httpsCallable(`newRequest`);

Firebase 문서: https://firebase.google.com/docs/functions/callable

SDK 를 개시할 수 없는 경우는, 다른 제안의 요점을 이하에 나타냅니다.

  • 파이어베이스 호스팅 및 호스트를 기본 위치에서 사용하는 경우 rewrites: https://firebase.google.com/docs/hosting/full-config#rewrites 를 선택합니다.
  • Krishnazden이 제안하는 CORS를 사용할 수도 있습니다.https://stackoverflow.com/a/53845986/1293220

내 요청에 대한 권한이 있기 때문에 이 방법만 사용할 수 있습니다.

exports.hello = functions.https.onRequest((request, response) => {
response.set('Access-Control-Allow-Origin', '*');
response.set('Access-Control-Allow-Credentials', 'true'); // vital
if (request.method === 'OPTIONS') {
    // Send response to OPTIONS requests
    response.set('Access-Control-Allow-Methods', 'GET');
    response.set('Access-Control-Allow-Headers', 'Content-Type');
    response.set('Access-Control-Max-Age', '3600');
    response.status(204).send('');
} else {
    const params = request.body;
    const html = 'some html';
    response.send(html)
} )};

함수의 오류를 발견하지 못하면 Cors 오류가 발생할 수 있습니다.은 '하다'입니다.try catch

const corsHandler = (request, response, handler) => {
    cors({ origin: true })(request, response, async () => {
        try {
            await handler();
        }
        catch (e) {
            functions.logger.error('Error: ' + e);
            response.statusCode = 500;
            response.send({
                'status': 'ERROR' //Optional: customize your error message here
            });
        }
    });
};

사용방법:

exports.helloWorld = functions.https.onRequest((request, response) => {
    corsHandler(request, response, () => {
        functions.logger.info("Hello logs!");
        response.send({
            "data": "Hello from Firebase!"
        });
    });
});

stackoverflow 사용자 덕분입니다.호앙 트린, 야요 아렐라노, 더그 스티븐슨

「」의 변경true타타에 "*"그래서 이렇게 생겼죠.

const cors = require('cors')({ origin: "*" })

일반적으로 이 응답 헤더는 다음과 같이 설정되어 있기 때문에 이 방법을 시도했습니다.

'Access-Control-Allow-Origin', '*'

이렇게 하면 도메인이 엔드포인트를 호출할 수 있으므로 안전하지 않습니다.

또한 다음 문서를 참조하십시오.https://github.com/expressjs/cors

나는 방금 그것에 관한 작은 글을 출판했다.

https://mhaligowski.github.io/blog/2017/03/10/cors-in-cloud-functions.html

일반적으로 Express CORS 패키지를 사용해야 합니다.이 패키지는 GCF/Firebase Functions의 요건을 충족하기 위해 약간의 해킹이 필요합니다.

도움이 됐으면 좋겠네요!

나도 합격할 때 .apponRequestfirebase 「요청 URL」의 후행 슬래시.가 Express를 .'/' .[project-id].cloudfunctions.net/[function-name]CORS ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」후행 슬래시를 추가했을 때 기대했던 반응이 나왔어요.

Express를 사용하지 않거나 단순히 CORS를 사용하고 싶은 경우.다음 코드가 문제 해결에 도움이 됩니다.

const cors = require('cors')({ origin: true, });   
exports.yourfunction = functions.https.onRequest((request, response) => {  
   return cors(request, response, () => {  
        // *Your code*
    });
});
  1. Google Cloud Functions로 이동합니다.이 플랫폼은 지금까지 본 적이 없지만, 이 FireBase 문제를 해결하는 방법입니다.
  2. 찾고 있는 Firebase 기능을 찾아 이름을 클릭합니다.이 페이지가 공백일 경우 클라우드 기능을 검색하여 결과에서 페이지를 선택해야 할 수 있습니다.
  3. 기능을 찾아 이름을 클릭합니다.
  4. 권한 탭으로 이동합니다.Add(사용자 추가)를 클릭합니다.
  5. 새 원칙에서 'allUsers'를 입력합니다. 입력을 완료하기 전에 자동으로 완료됩니다.
  6. 역할 선택에서 Cloud Functions를 검색한 후 Invoker를 선택합니다.
  7. 절약하다.
  8. 몇 분만 기다려.

이걸로 고칠 수 있을 거야문제가 해결되지 않으면 다음과 같이 기능 코드에 CORS 솔루션을 추가합니다. 솔루션을 추가합니다.

  exports.sendMail = functions.https.onRequest((request, response) => {
  response.set("Access-Control-Allow-Origin", "*");
  response.send("Hello from Firebase!");
});

FireBase에 .localhost클라우드 대신." " " 입니다.firebase serve ★★★★★★★★★★★★★★★★★」firebase emulators:start웹 앱에서 사용할 때 로컬 호스트가 아닌 서버로 함수를 가리킵니다.

firebase init 스크립트 뒤에 html 헤더에 다음 스크립트를 추가합니다.

 <script>
      firebase.functions().useFunctionsEmulator('http://localhost:5001')
 </script> 

코드를 서버에 전개할 때는, 반드시 이 스니펫을 삭제해 주세요.

클라이언트 측에 존재하지 않는 함수를 호출하고 있었기 때문에 에러가 발생했습니다.예를 들어 다음과 같습니다.

firebase.functions().httpsCallable('makeSureThisStringIsCorrect');

제 경험담을 더하고 있습니다.왜 CORS 에러가 났는지 알아내기 위해 몇 시간을 보냈습니다.

클라우드 기능의 이름을 변경한 적이 있습니다(대규모 업그레이드 후 처음 시도).

따라서 내 파이어베이스 앱이 잘못된 이름으로 클라우드 함수를 호출했을 때 CORS 오류가 아니라 404 오류를 발생시켰어야 했습니다.

파이어베이스 앱에서 클라우드 기능 이름을 수정하면 문제가 해결되었습니다.

이에 대한 버그 보고서를 작성했습니다.https://firebase.google.com/support/troubleshooter/report/bugs

이렇게 많은 검색을 통해 동일한 FireBase 문서에서 이 솔루션을 찾을 수 있었습니다. 경로에서 Cors를 구현하기만 하면 됩니다.

import * as express from "express";
import * as cors from "cors";


const api = express();
api.use(cors({ origin: true }));
api.get("/url", function);

FireBase 문서 링크: https://firebase.google.com/docs/functions/http-events

단일 핸들러 함수를 만들고 싶은 경우(참조 답변)

const applyMiddleware = handler => (req, res) => {
  return cors(req, res, () => {
    return handler(req, res)
  })
}
exports.handler = functions.https.onRequest(applyMiddleware(handler))

Firebase(30분 전 등록)는 초보자입니다.문제는 엔드 포인트에 전화를 걸었다는 것입니다.

https://xxxx-default-rtdb.firebaseio.com/myendpoint

대신

https://xxxx-default-rtdb.firebaseio.com/myendpoint.json

한 지 안 된 Firebase를..json내선 번호

나는 이것을 오랫동안 시도해 왔다.

내가 이 변화를 주었을 때 마침내 효과가 있었다.

app.get('/create-customer', (req, res) => {
  return cors()(req, res, () => {
    ... your code ...

점은 가 장 the the the the the the the the the the the the the the the the the the the the를 사용했다는 것이다.cors()(req, res...(직접)가 cors(req, res...

이제 완벽하게 작동합니다.

devtool 콘솔에서도 동일한 access allow control origin 오류가 발생하여 보다 현대적인 구문을 가진 다른 솔루션을 찾았습니다.

저의 CORS 문제는 스토리지(RTDB도 브라우저도 아님)에 있었습니다.그 후 신용카드를 소지하고 있지 않습니다(앞서 설명한 솔루션에서 요청한 바와 같이). 카드 없음 솔루션은 다음과 같습니다.

  1. install gsutil : https://cloud.google.com/storage/docs/gsutil_install#linux-and-macos

  2. gsutil을 사용하여 터미널을 통해 로드되는 cors.json 파일을 작성하다

gsutil cors set cors.json gs://[ your-bucket ]/-1.appspot.com

https://firebase.google.com/docs/storage/web/download-files#cors_configuration

제 경우 클라우드 함수 호출기 제한 액세스로 인해 오류가 발생했습니다.클라우드 함수 호출기에 allUsers를 추가하십시오.링크를 잡으세요.자세한 내용은 문서를 참조하십시오.

다른 솔루션이 모두 동작하지 않는 경우는, 콜의 개시시에 다음의 주소를 추가해, CORS 를 유효하게 합니다.리다이렉트 합니다.

https://cors-anywhere.herokuapp.com/

JQuery AJAX 요청이 있는 샘플 코드:

$.ajax({
   url: 'https://cors-anywhere.herokuapp.com/https://fir-agilan.web.app/gmail?mail=asd@gmail.com,
   type: 'GET'
});

Express with CORS 설정 방법에 대해서는 아래를 참조하십시오.

'https://pericope.app'은 Firebase 프로젝트의 커스텀 도메인입니다.

다른 모든 답변이 권장되는 것 같습니다.origin:true또는*.

다른 사람이 api에 접속할 수 있기 때문에 모든 origin을 허용하는 것은 망설여집니다.공용 서비스를 생성하는 경우에는 괜찮지만, 데이터를 사용하여 작업을 수행하는 경우에는 권한이 있는 환경이기 때문에 위험합니다.예를 들어 이 관리 SDK는 Firestore 또는 스토리지에 대해 설정한 보안 규칙을 무시합니다.

//Express
const express = require('express');
const app = express();

const cors = require('cors');
app.use(cors({
  origin: 'https://pericope.app'
}));

https.onRequest에서 다음과 같이 typescript를 사용하여 cors를 사용합니다.

import * as cors from 'cors';
const corsHandler = cors({origin: true});

export const pingFunctionWithCorsAllowed = functions.https.onRequest((request, response) => {
  corsHandler(request, response, () => {
    response.send(`Ping from Firebase (with CORS handling)! ${new Date().toISOString()}`);
  });
});

원본에서

언급URL : https://stackoverflow.com/questions/42755131/enabling-cors-in-cloud-functions-for-firebase

반응형