Cloud Functions CORS Setting

Toprak Erzurumluoğlu
3 min readMar 11, 2020

--

Bir kere de olsa api hazırlayıp bir uygulama üzerinden istek yapmayı denemişseniz şu hatayı almışsınızdır.

… has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

Bu aslında bir hata değil, tarayıcınız tarafından size iletilen bir güvenlik mesajıdır ve Api’ ye yapılan isteğin adresini Api tanımadığı zamanlarda alırız.

codecademy.com’ da güzel bir benzetme yapılmış bununla ilgili : “Bir merdivene ihtiyacınız var komşunuzdan alabilirsiniz bunda bir mahsur yoktur, ancak dışardan bir satıcıdan aldığınızda bu merdiven sitenizin güvenliğine takılır.”

“For example, if you need to borrow a ladder, you could ask a neighbor in the building who has one. The building’s security would likely not have a problem with this request (i.e., same-origin). If you needed a particular tool, however, and you ordered it from an outside source like an online marketplace (i.e., cross-origin), the security at the entrance may request that the delivery person provide identification when your tool arrives.” — codecademy

Bu nedenle biz de istek gelecek adresleri, türlerini apimizi henüz hazırlarken tanıtacağız, kısacası şu adresten gelen GET isteklerine izin ver diyeceğiz.

Daha önceden hazırlamış ve Github’ a da eklemiş olduğum Function’ a anlattığım şekilde izinleri verelim.

Bağımlılıkları Dahil Edelim

npm install cors        // gerekli
npm install @types/cors // typescript için gerekli (js için değil)

İndirmeler tamamlandıktan sonra

import * as cors from 'cors';

Bu şekilde projemde kullanmak için dahil ediyorum.

Artık cors’ tan bir nesne üretip kullanabilirim.

const corsHandler = cors({ origin: '*' });

Origin string ya da string listesi alabilir. Bu stringlerde izin vereceğimiz url leri tanımlayacağız. Eğer ‘*’ yazarsak her adresten gelecek isteklere izin vermiş oluruz. Test aşamasında kullanırken direkt * vererek kullanabiliriz.

Ben kendi local projemde kullanacağım için adresi localhost vereceğim. Ve gelecek istek türü için de sadece GET olanları kabul edeceğim.

const corsHandler = cors({ origin: 'localhost:4200', methods: 'GET' });

Sonrasında

Ana method bloğunu corsHandler içine almam yeterli

export const GetPosts = functions.https.onRequest((req, res) => {
corsHandler(req, res, () => {
const posts: Post[] = [];
var param: any[] = isParameterValid(req.query.catId);
... }});

Ben şekli biraz daha düzelsin diye bir main metotu tanımlayarak main metotunu cors içine alıyorum.

export const GetPosts = functions.https.onRequest((req, res) => {
corsHandler(req, res, () => {
main();
});
function main() {
const posts: Post[] = [];
var param: any[] = isParameterValid(req.query.catId);
if (param[0] === false) {
res.status(404).send('Anlamsız Parametre!');
} else {
getPost(param[1]).then((p: any[]) => {
if (p.length == 0) {
res.status(404).send('Bu kategoride henüz hiç yazı bulunamadı!');
} else {
p.forEach(element => {
const post: Post = new Post(element.postId, element.postTitle, element.postContent);
posts.push(post);
});
res.send(posts);
}
}).catch(e => {
res.status(500).send(e);
});
}
}
});

Bir de söylemiştim. Cors Origin olarak string dizi de verebiliyoruz. Onu da şu şekilde güzelleştirmekte fayda var.

const corsHandler = cors({ origin: getWhiteListURL());....function getWhiteListURL() : string[]{
return ['http://localhost:4200','http://example.com'];
}

Hatta İzin verilecek adresleri veritabanınızdan getirmek gayet hoş bir çözüm olacaktır.

Bence önemli konulardan biriydi umarım sizler için de öyle olan bir konuyu ele almışımdır.

Projenin tamamına GitHub üzerinden erişebilirsiniz.

--

--