Firebase: Cross-origin redirection to (url) denied by Cross-Origin Resource Sharing policy:Status code: 301 [duplicate] - http

This question already has answers here:
NextJs CORS issue
(10 answers)
Closed 8 months ago.
I am trying to deploy a firebase function and call the function from a nextjs app. The function works when it runs on firebase emulator, and when it is deployed I am able to call the function from postman. However, when deployed and I try to call using fetch I get an error. I have also tried to deploy the website to call from a different url but still get the same error.
Here is the calling function:
export async function getArticle(articleURL) {
const response = await fetch(articleURL);
const json = await response.json();
return json.result;
}
Here is the firebase function that I am trying to call:
const cors = require('cors')({origin: true});
exports.getArticle = functions
.runWith({
timeoutSeconds: 120,
memory: "1GB",
})
.https.onRequest(async (req, response) => {
cors(req, response, async() => {
try {
{code}
response.status(200).json({ result: 'test' });
}
catch (e) {
response.status(400).json({ result: "error", message: e.message });
}finally {
{code}
}
})
});
I have also tried adding headers such as:
response.set('Access-Control-Allow-Origin', "*");
response.set('Access-Control-Allow-Headers', "*");
but nothing seems to work. I have tried for hours but nothing works. The error I get is:
[Error] Cross-origin redirection to (url) denied by Cross-Origin Resource Sharing policy: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Status code: 301
[Error] Fetch API cannot load (url) due to access control checks.
[Error] Failed to load resource: Cross-origin redirection to (url) denied by Cross-Origin Resource Sharing policy: Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. Status code: 301
[Error] Unhandled Promise Rejection: TypeError: Load failed
Lastly, I have also tried adding parameters to my fetch call such as :
fetch(URL, {
mode: 'cors',
headers: {
'Access-Control-Allow-Origin':'*'
}
})
Overall, nothing seems to work and don't know what else to try. Any help would be greatly appreciated.

The problem was not with the firebase function but with the api call on nextjs. I was importing the function and making the call from a component. Instead I found the solution on this post: NextJs CORS issue.
The solution that worked for me was by chispitaos. I changed my getArticle function to the api format and fetched the internal api which then fetched the firebase function. Here was my new function:
export default async function handler(req, res) {
try {
const response = await fetch(`any url`);
const json = await response.json();
console.log(json);
res.status(200).send(json);
} catch (error) {
console.error(error)
return res.status(error.status || 500).end(error.message)
}
}
and here was how I called it :
const newData = await fetch('/api/getArticle');
This fixed the issue for me.

Related

NgRok not reading method

node js, and ngRock, it seems that ng rock is not receiving the GET method every time i make a GET request the method deployed in ngrok is OPTIONS /category, instead of GET / category.
picture
and im not getting any response from the server
react fetch
try {
const response = await fetch(global.config.Node_API + 'categorias', {
method: 'GET'
});
if (!response.ok) {
throw new Error(`Error!, Fallo en la coneccion`);
}
const result = await response.json();
this.setState({cont:1,categor: result});
} catch (err) {
console.log(err.message);
}
in the console im getting error
Access to fetch at 'https://5833-45-229-42-135.ngrok.io/categorias' from origin 'http://localhost:3001' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
in nodeJs im using
app.use(cors())

Trying to implement shopify webhooks but getting 'InternalServerError: stream is not readable'

I'm building an app for shopify and need to add the GDPR webhooks. My back end is handled using next.js and I'm writing a webhook handler to verify them. The docs havent been very helpful because they dont show how to do it with node. This is my verification function.
export function verifiedShopifyWebhookHandler(
next: (req, res, body) => Promise
): NextApiHandler {
return async (req, res) => {
const hmacHeader = req.headers['x-shopify-hmac-sha256'];
const rawBody = await getRawBody(req);
const digest = crypto.createHmac('sha256', process.env.SHOPIFY_API_SECRET).update(rawBody).digest('base64');
if (digest === hmacHeader) {
return next(req, res, rawBody);
}
const webhookId = req.headers['x-shopify-webhook-id'];
return res.status(401).end();
};
}
But I get this Error: error - InternalServerError: stream is not readable
I think it has to do with now Next.js parses the incoming requests before they are sent to my api. Any ideas?
I discovered the answer. Next.js was pre parsing the body in the context which made it so that I couldn't use the raw body parser to parse it. By setting this:
export const config = {
api: {
bodyParser: false
}
};
above the api function in the api file it prevented next from parsing it and causing the issue. I found the answer because people had the same issue integrating swipe and using the bodyParser.

Axios post request to Firebase Auth REST API produces 400 error

I have an instance of Axios:
import axios from 'axios';
const instance = axios.create({
baseURL: 'https://identitytoolkit.googleapis.com/v1'
});
export default instance;
Then I import it in my signup.vue file:
<script>
import axios from '../../axios-auth';
...
</script>
In that Vue file I have a signup form, which runs the following method once I hit the Submit button:
onSubmit() {
const formData = {
email: this.email,
age: this.age,
password: this.password,
confirmPassword: this.confirmPassword,
country: this.country,
hobbies: this.hobbyInputs.map(hobby => hobby.value),
terms: this.terms
};
console.log(formData);
axios.post('/accounts:signUp?key=my_key_goes_here', {
email: formData.email,
password: formData.password,
returnSecureToken: true
})
.then(res => {
console.info(res);
})
.catch(error => {
console.error(error);
});
}
I'm getting a 403 error - forbidden 400 error - bad request.
I tried to change headers:
instance.defaults.headers.post["Access-Control-Allow-Origin"] = "localhost";
instance.defaults.headers.common["Content-Type"] = "application/json";
But that didn't help.
I'm working from localhost and I saw that localhost is allowed by default. I tried also to add 127.0.0.1 to the list, but that also didn't help.
What am I missing? How can I make this request work?
If you get a 400 error it is maybe because you get an error from the API itself:
Common error codes
EMAIL_EXISTS: The email address is already in use by another account.
OPERATION_NOT_ALLOWED: Password sign-in is disabled for this project.
TOO_MANY_ATTEMPTS_TRY_LATER: We have blocked all requests from this device due to unusual activity. Try again later.
As a matter of fact, those errors return an HTTP Status Code of 400.
You can see the exact response message (e.g. EMAIL_EXISTS) by doing the following with axios:
axios.post('/accounts:signUp?key=my_key_goes_here', {
email: formData.email,
password: formData.password,
returnSecureToken: true
})
.then(res => {
console.info(res);
})
.catch(error => {
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.log(error.response.data);
} else if (error.request) {
console.log(error.request);
} else {
console.log("Error", error.message);
}
});
See https://github.com/axios/axios#handling-errors
I agree with you as i have tried many approaches but was not getting the result. Hence i have tried to change the code.
You need to make two changes in your code.
1] You need to comment the instance.defaults.headers.post["Access-Control-Allow-Origin"] = "localhost"; because you are providing the authentication globally. As, firebase provides the feature of authentication and you are connecting the web app with REST API.
2] You need to add { headers: {'Content-Type': 'application/json' } in the axios.post() method to prevent it from CORS Error.
Following this approach i hope you can get the respective output.
Happy Coding!
Directly call
https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=[yourkey]
No need to keep it in a separate file
Anyone who comes to the thread in future. I faced this issue and lost in debugging and worked with fetch. It was tiresome and took me a day but i made axios work. Here is the code.
const data = JSON.stringify({
idToken: authContext.token,
password: enteredNewPassword,
returnSecureToken: false,
});
// Send the valid password to the endpoint to change password
axios
.post(
"https://identitytoolkit.googleapis.com/v1/accounts:update?key=[Your Key]",
data,
{
headers: {
"Content-Type": "application/json",
},
}
)
.then((response) => {
console.log(response.data);
})
.catch((err) => {
console.log(err.message);
});
Remember to Stringify the data you want to send. Stringify it outside of the http request and then pass that variable. Don't know why but this helps!
Lastly remember to add the header when sending the request to firebase. Make sure axios.post is on the same line. My formatter gave a line break which was also cause of error.
Hope it helps :)

How can I prevent "Bad request" when calling Firebase's `.onCall()` method?

I've just upgraded to using Firebase Cloud Functions v1.x. According to this answer
Callable functions are exactly the same as HTTP functions
With that in mind, I've tried to convert my pre-1.x mock-code:
export const myHttpAction = functions.https.onRequest((req, res) => {
try {
const result = await myHttpActionWorker(req.body);
return res.send({ status: 'OK' });
} catch (err) {
console.error(err);
return res.status(500).send({ status: 'Server error' });
}
});
to the following:
export const myHttpAction = functions.https.onCall(async (data, context) => {
console.log(context.auth);
try {
const result = await myHttpActionWorker(data);
return { status: 'OK' };
} catch (err) {
console.error(err);
return { status: 'Server error' };
}
});
But upon submission to my endpoint, /myHttpAction, with the same data that I used in pre-1.x, I get the following back:
{
"error": {
"status": "INVALID_ARGUMENT",
"message": "Bad Request"
}
}
I'm not sure why the request is "bad" since it's exactly the same and Callable functions are "exactly the same". Any idea what gives?
My package.json specifies "firebase-functions": "^1.0.1".
You're misunderstanding what was meant by "exactly the same" (and omitting the entire remainder of the answer!). They're the same in terms of security (as the original question was asking), because a callable function is an HTTP function, with extra stuff going on behind the scenes that managed by the callable client SDK. The answer lists out those differences. Those differences don't have any effect on security. But you can't simply swap in a callable for an HTTP function and expect everything to be the same for existing callers.
If you want to invoke a callable function without using the client SDK, you'll have to follow its protocol specification. The documentation on that is forthcoming, but you can get the basics here:
How to call Firebase Callable Functions with HTTP?

Firebase HTTP function CORS

I'm still having problems with CORS when using Firebase HTTP functions.
Here is my web console error:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:3000' is therefore not allowed access. The
response had HTTP status code 404.
Here is my function:
const cors = require('cors')({ origin: true });
const express = require('express');
const functions = require('firebase-functions');
const app = express();
const validate_user = require('./validate_user_id_token.js');
const charge_card = async(req, res) => {
// ...
}
app.use(cors);
app.use(validate_user);
app.use(charge_card);
exports.foo = functions.https.onRequest(app);
I think I've read over every single Firebse CORS question. I also have a near replica of the sample provided here.
Please help :)
Edit:
The URL I am calling is correct (used texdiff.com just to be sure, and functions logs are showing it as executed but returning 404). For reasons unknown, a 404 is returned regardless. Perhaps that is CORS mechanism?
Update:
I got things working without using express by putting using cors() in my onRequest handler:
exports = module.exports = functions.https.onRequest(async(req, res) => {
cors(req, res, () => {});
await charge_card(req, res);
});
Not ideal, but it works for now :/
According to the Firebase documentation, there are a couple of references to CORS configuration:
Using CORS:
You can enable the use of CORS by calling it within the function, just like you did in your update to the question:
// Usage of the `cors` express middleware
return cors(req, res, () => {
// TO-DO
});
Also if you have an already existing Express app, you can then enable CORS by doing:
const app = express();
app.use(cors({ origin: true }));
This is what you had already done on the first step, but there's the difference in the { origin: true } definition, so maybe that is related.
In any case, as per the documentation it looks like it is indeed fine to add the cors within the request.

Resources