How can i fix CORS error firebase function - javascript

I currently have a CORS problem that I can't solve, here is my code:
gogologo.js
const souscription = async (req, res) => {
if (!req.body.data || !req.body.data.souscrireParams) {
console.error('souscription input error')
res.json({ data: { error: 'souscription input error' } })
return
}
const souscrireParams = req.body.data.souscrireParams
console.log('souscription:', JSON.stringify(req.body.data.souscrireParams))
var data = JSON.stringify(souscrireParams)
const headers = {
'x-api-key': apiKey,
'Content-Type': 'application/json'
}
var reqConfig = {
method: 'post',
url: 'url',
headers: headers,
data: data
};
console.log("reqConfig = ", reqConfig)
try {
const response = await axios(reqConfig)
const result = response.data
if (result.resultat === 'success') {
res.json({ data: result })
} else {
const msg = {
to: 'mail',
from: 'mail',
subject: 'souscription Fail',
html: `deal <br><br> ${JSON.stringify(souscrireParams)}<br><br>Error:<br><br>`,
}
sgMail.setApiKey(sgKey)
await sgMail.send(msg)
res.json({ data: { error: { message: 'souscrire error' } } })
}
} catch (error) {
console.log('error message : ', error.message)
console.log('error : ', error)
const msg = {
to: 'mail',
from: 'mail',
subject: 'souscription fail',
html: `deal <br><br> ${JSON.stringify(souscrireParams)}<br><br>Error:<br><br>${JSON.stringify({ error: error.message })}`,
}
sgMail.setApiKey(sgKey)
await sgMail.send(msg)
res.json({ data: { error: error.message } })
}
}
exports.souscription = souscription
index.js
exports.souscription = functions.runWith({
vpcConnector: 'app-functions-connector',
vpcConnectorEgressSettings: 'ALL_TRAFFIC'
}).https.onRequest(async (req, res) => {
console.log('souscription IP:', await publicIp.v4())
cors(req, res, async () => {
gogologo.souscription(req, res)
})
})
when I press the subscribe button, it displays an error message "Access to fetch at 'url genereted by firebase function' from origin 'url app' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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."
with a post error.

Related

CORS response when sending a DELETE request

I am trying to send a DELETE request to my backend server, but I keep getting this response printed to my console:
Response {type: 'cors', url: 'http://localhost:3003/delete', redirected: false, status: 200, ok: true, …}
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "cors"
url: "http://localhost:3003/delete"
[[Prototype]]: Response
I don't know why this is happening.
server.js
const express = require('express')
const knex = require('knex')
const cors = require('cors')
const db = knex({
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'postgres',
password: 'psql',
database: 'blogspot',
port: 5432
}
});
const app = express();
app.use(express.json())
app.use(cors())
// Delete Blog
app.delete('/delete', (req, res) => {
const {id} = req.body;
db.select('*').from('blogs')
.where({
id: id
})
.del()
.then(() => {
res.json('Deleted Successfully')
})
.catch(err => res.status(404).json('An error occured'))
})
fetchAPI.js
function deleteBlog (blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
}).then(resp => {
console.log(resp)
if (resp === 'Deleted Successfully') {
navigate(0)
} else if (resp === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}
I keep getting 'ERROR' printed to my console along with the cors response I pasted above. When I refresh, I find that the blog has been deleted, but the response was definitely an error since navigate(0) wasn't run and ERROR was printed to my console. I have tried removing the 'Content-Type': 'application/json' header and sending the id as request params instead but I got the same error.
The fact that the response is of type "cors" just means that some contents are filtered by CORS policy (see https://developer.mozilla.org/en-US/docs/Web/API/Response/type) but you didn't get any error code, the statusCode is 200.
Since your response content type is JSON, you must also resolve the json parsing before reading the response:
function deleteBlog(blog) {
fetch('http://localhost:3003/delete', {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(blog)
})
.then(data => data.json())
.then(resp => {
// I also suppose that you will more likely find
// your "Deleted successfully" in the resp.body property, so :
if (resp.body === 'Deleted Successfully') {
navigate(0)
} else if (resp.body === 'An error occured') {
console.log('Something went wrong')
} else {
console.log('ERROR')
}
})
}

'Access-Control-Allow-Credentials' header in the response is ' ' which must be 'true' when the request's credentials mode is 'include' [duplicate]

This question already has answers here:
'Access-Control-Allow-Credentials' header in the response is '' which must be 'true'
(2 answers)
Closed 2 years ago.
I am learning server-client communication in the course of making MMORPG project.
*update: server side code is edited.
This is server side code.
router.post('/login', async (request, response, next) => {
passport.authenticate('login', async (error, user) => {
try {
if (error) {
return next(error);
}
if (!user) {
return next(new Error('email and password are required'));
}
request.logIn(user, { session: false }, (err) => {
if (err) {.....
This is client side code
function postData(url, data = {}) {
return fetch(url, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
redirect: 'follow',
body: JSON.stringify(data),
}).then((response) => response.json());
}
login() {
const loginValue = this.loginInpout.value;
const passwordValue = this.passwordInput.value;
postData('http://localhost:4000/login', { email: loginValue, password: passwordValue })
.then((response) => {
if (response.status === 200) {
this.startScene('Game');
} else {
console.log(response.message);
window.alert('invald username or password');
}
}).catch((error) => {
console.log(error.message);
window.alert('invald username or password');
});
}
when login() function is called, fetch() function throws this message in browser console.
(http://localhost:4000/login) is server side and (http://localhost:8000) is client side.
Access to fetch at 'http://localhost:4000/login' from origin 'http://localhost:8000'
has been blocked by CORS policy: Response to preflight request doesn't pass access
control check: The value of the 'Access-Control-Allow-Credentials' header in the
response is '' which must be 'true' when the request's credentials mode is 'include'.
LoginScene.js:48 POST http://localhost:4000/login net::ERR_FAILED
Failed to fetch <<-- fetch error message on browser console
I tried to fix it many different ways with no good outcome.
Try the following code:
import express from "express";
import http from "http";
const app = express();
const server = http.createServer(app);
const sio = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});
sio.on("connection", () => {
console.log("Connected!");
});

Can not download file while sending request from one node.js server to another

I am facing some issue while downloading file using node.js. I have scenario like my angular component is sending the file request. in my first node server I am doing the token validation and then redirecting to another node server where actually the execution happens. I am explaining my code below.
service.ts:
submitAndDownloadFile(formdata : any ){
const token = localStorage.getItem('token')
let headers = new HttpHeaders({
Authorization: 'Basic ' + token
})
const cecID = localStorage.getItem('cec');
const AppUrl = `${environment.nodeJsBaseUrl}:${environment.hostingNodeJsContainerPort}/convert-test-cases/${cecID}`;
return this.httpClient.post(AppUrl, formdata, { responseType: 'blob', observe : 'response', headers : headers});
}
Here I am sending the request to my first node.js server which code has given below.
app.js(first:port-8000):
router.post('/convert-test-cases/:id', middleware.auth, (req, res) => {
try{
let postRequestOptions = {
url: '',
method: 'POST',
json: true,
headers: {},
body: {},
};
postRequestOptions.url = 'http:localhost:9000/convert-test-cases';
postRequestOptions.headers = {
'Content-Type': 'application/json',
};
postRequestOptions.body = req.body;
request(postRequestOptions, async (error, response, pathList) => {
if(error) {
console.log('error', error);
}else{
res.send(pathList);
}
})
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here I am doing the token validation using middleware.auth and sending same request to another node.js file which code is explained below.
app.js:(second-port-9000):
router.post('/convert-test-cases', async (req, res) => {
try{
let response = await ctcCtrl.convertTestCase(req.body, req.files);
if(response.status == 'success'){
res.set('Access-Control-Expose-Headers','*, Content-Disposition');
return res.download(response.fileName,response.fileName);
}else{
return res.send(response);
}
}catch(e){
responseObj = {
status: 'error',
msg: 'Error occurred while processing your request',
body: null
}
return res.send(responseObj);
}
})
Here only I am doing some execution and downloading the file. If I am connecting angular to node-9000 its working fine but my requirement is first I have to connect to port-8000 to some token validation and after that I have to send same req.body and re.file to app.js which is running in 9000 using request module. As per my code its not working at all.

Axios request to Gmail API unauthorised error?

I have tried to send, with Google API and Axios, a new email:
async SendMail (req, res) {
try {
const email = `From: ${req.body.sender}\r\n` + `To: ${req.body.receiver}\r\n` + `Subject: ${req.body.subject}\r\n\r\n` + req.body.message
const response = await axios.post(`https://www.googleapis.com/upload/gmail/v1/users/${req.body.userId}/messages/send`, email, {headers: {Authorization: `Bearer ${req.body.token}`, 'content-type': 'message/rfc822'}})
res.status(200).send({data: response.data, status: 'ok'})
} catch(err) {
console.log('error => ', err)
res.status(404).send({
error: 'Error for the recuperation of Google info'
})
}
}
It tells me I am unauthorised but I have added the correct scopes.
error: {
response: {
status: 401,
statusText: 'Forbidden',
...
}
}
The accessToken is working I have done a call with a get with it and it worked pretty fine.
This is my scope: https://mail.google.com/

Node request how to handle sessions

I'm using node.JS with request module.
My problem is, I need to authenticate the user on every request because the session is destroyed outside of the .then((response) => {}) block.
How is it possible to save the created session in a class for later use?
I tried out everything without success.
Here is a not working code snippet
login() {
const getLoginUrl = 'https://www.demourl.com/'
const postLoginUrl = 'https://www.demourl.com/account/login/'
rp({
url: getLoginUrl,
jar: this.cookieJar,
method: 'GET'
})
.then((body) => {
var csrftoken = this.cookieJar.getCookies(getLoginUrl)[1].toString().split('=')[1].split(';')[0];
var args = {
url: postLoginUrl,
json: true,
method: 'POST',
data: {
username: this.username,
password: this.password
},
headers: {
'method': 'POST',
'path': '/account/login/',
'cookie': 'csrftoken=' + csrftoken,
},
jar: this.cookieJar,
resolveWithFullResponse: true
}
rp(args)
.then((response) => {
//Here is a valid session
//But how can I use this session in different functions?
console.log('Post demourl.com/account/login success');
})
.catch((error) => {
console.log('Post demourl.com/account/login error: ', error);
});
})
.catch((error) => {
console.log('Get demourl.com error: ', error);
});
}
you should use this function as a middleware and then attach what ever you want to attach in to your req
try in you main script do
'use strict'
const express = require('express');
const login = require('./login');
const app = express()
app.use(login);// use this if you want all your routes to check login or put it in a specific route
app.get('/', (req,res)=>{
//this route is only for loged in users
});
const server = http.createServer(app).listen(process.env.PORT);
module.exports = app;
and in your login script
const login = (req, res, next) => {
const getLoginUrl = 'https://www.demourl.com/'
const postLoginUrl = 'https://www.demourl.com/account/login/'
rp({url: getLoginUrl, jar: this.cookieJar, method: 'GET'})
.then((body) => {
var csrftoken = this.cookieJar.getCookies(getLoginUrl)[1].toString().split('=')[1].split(';')[0];
var args = {
url: postLoginUrl,
json: true,
method: 'POST',
data: {
username: this.username,
password: this.password
},
headers: {
'method': 'POST',
'path': '/account/login/',
'cookie': 'csrftoken=' + csrftoken,
},
jar: this.cookieJar,
resolveWithFullResponse: true
}
rp(args)
.then((response) => {
res.loginResponse = response; // save the response for later use
console.log('Post demourl.com/account/login success');
next();
})
.catch((error) => {
console.log('Post demourl.com/account/login error: ', error);
return res.send(error) //send the error
});
})
.catch((error) => {
console.log('Get demourl.com error: ', error);
return res.send(error) //send the error
});
}
module.exports = login
I never see this.cookieJar being defined. Make sure it's initialized somewhere:
this.cookieJar = request.jar();
If you only use a single cookieJar in your application, you could also use Request's global cookie jar by setting the option jar to true:
// Either by setting it as the default
const request = require('request').defaults({jar: true});
// Or by setting it on each request
request('www.example.com', { jar: true });

Categories

Resources