Unable to make an API request to Twitter for .json return duo to CORS - Chrome extension- Manifest 3 - google-chrome-extension

I am trying to build a basic Chrome that shows an HTML page that I built on chrome://newtab. (Manifest 3).
Flow: My HTML file calls a local script file. The script file has a fetch function. The function calls the twitter 2.0 API with GET and a bearer auth to fetch all of the tweets made by a specific account. Account is recognized by id from twitter.
Results from the console:
"Access to fetch at 'https://api.twitter.com/2/users/44196397/tweets' from origin 'chrome-extension://epfgicoboagicldadiiggnmfgholpmna' 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."
The code I use:
fetch("https://api.twitter.com/2/users/44196397/tweets", {method: 'GET', headers : {Authorization : "Bearer ..🤫.."}}) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error));
Manifest includes: version:3, name, version, decription, author, chrome_url_overrides {newtab: index.html}, permissions [storage].
Tried:
no-cors header in fetch() - getting 401 error (according to Google, not supported on the blue side)
Postman - worked
curl commend on my PC - worked
Placing the script on an external server (I thought there is some sort of a security blockade for extensions, so then I could just extract the text) - CORS error also there. (On 000webhosting, no access to server config).
So from here on out, I'm stuck.I will highly appreciate any feedback!
Note: I'm new. Please ELI5, started programming with ChatGPT. Sorry if the post is overdetailed, didn't want to overlook something which might be important.
Cheers!

Related

HTTP request working from Postman and Node but not React

There are a few questions similar to this on Stack Overflow, and none of the proposed solutions worked, so I'll walk through the case and what I've tried.
I have a server application hosted on Cloud Run, which can only be accessed with the appropriate Bearer token in the request Authorization header. I've tried accessing it via Postman and an Axios request from a local Nodejs server, with the Authorization header, and it worked fine. With React (create-react-app specifically), I get the following error: Access to XMLHttpRequest at 'https://myserver-lhp5a9xp5a-ue.a.run.app/api/rules' from origin 'http://localhost:3000' 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.
On the server side, I get the 403 error that Cloud Run gives when the incorrect Authorization token is passed. Also, when I allow unauthenticated access from the Cloud Run side (so remove the need for an Authorization header), the request works fine, so it looks like this is indeed an issue with the Authorization header and not CORS.
In addition, I'm handling CORS on the server side. Here's my server-side code:
var express = require('express');
var router = express.Router();
const cors = require('cors');
router.options('/api/rules', cors());
router.get('/api/rules', cors(), (req, res, next) => {
res.status(200).send()
});
Here's my React code:
const axiosInstance = axios.create({
baseURL: process.env.REACT_APP_API_BASE_URL
});
const buttonClickHandler = async (event) => {
const resp = await axiosInstance.get('/api/rules'
, {
headers: {
'Authorization': 'Bearer eyJhbGciOiJSUzI1NiIsImtpZ...' // I used this token within the same minute when trying the request via Postman or from my Nodejs app, so a token expiry isn't the issue.
}
}
)
console.log(resp.data)
}
Here's what I tried so far:
Using fetch instead of axios - same error
Using the same token, within the same 5 seconds, to send the request from Postman or a Nodejs server - it worked fine.
Using an axios interceptor to set the Authorization - same error
Removing the single quotes around Authorization - same error
Sending the request to my Nodejs server instead and doing a console.log of the header to make sure the Authorization token is being passed correctly (it is)
Not using an an axios instance but spelling out the full URL in the request - same error
Trying a different endpoint on my Cloud Run server - same error
Deploying my React app to be served from a https endpoint and sending the request from there - same error
Adding Accept: '*/*' to the headers
Adding 'Accept': '*/*' to the headers
Adding 'Content-Type': 'application/json' to the headers
All combinations of the three above points
I found the answer after some digging, thanks #aniket-kolekar for pointing me in the right direction.
When Postman or a Nodejs server query an endpoint like GET, POST, PUT, DELETE, they send the call without checking the OPTIONS first. Create-React-App does.
The service I was querying is hosted on Cloud Run and doesn't allow unauthenticated invocations. So while I was including the authorization header to make my GET call, it wasn't being included in the pre-flight OPTIONS call. In fact, CORS prevents auth headers from being included in an OPTIONS call.
A Cloud Run PM replied in this post that this is a known issue with Cloud Run. The way I'll get around it for now is to host two services on Cloud Run - one that doesn't require authentication, and effectively acts as a proxy server to route calls from the client service to the shielded server service.
TLDR;
CORS is a mechanism built into the web browser. It’s not a UI code issue.
To fix CORS problems, you need to make changes on the API (server) side.
Here is the behind the scenes working:
Browser: Sends OPTIONS call to check the server type and getting the headers before sending any new request to the API endpoint. Where it checks for Access-Control-Allow-Origin. Taking this into account Access-Control-Allow-Origin header just specifies which all CROSS ORIGINS are allowed, although by default browser will only allow the same origin.
Postman: Sends direct GET, POST, PUT, DELETE etc. request without checking what type of server is and getting the header Access-Control-Allow-Origin by using OPTIONS call to the server.
You will have to configure Access-Control-Allow-Origin header in your server to resolve the CORS issue.

Google maps API returning No 'Access-Control-Allow-Origin' with Node.js module

I am using the node module #googlemaps/google-maps-services-js to make requests to the Google maps API. When I make requests to any of their API endpoints (e.g directions API, places API, etc), I get these errors:
xhr.js:125 Refused to set unsafe header "User-Agent"
xhr.js:125 Refused to set unsafe header "Accept-Encoding"
localhost/:1 Access to XMLHttpRequest at 'https://maps.googleapis.com/maps/api/directions/json?
destination=Universal%20Studios%20Hollywood&key=mykey&origin=Disneyland' from
origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header
is present on the requested resource.
Here are the things I've tried:
1. I've tried accessing different API endpoints, (e.g instead of directions, places.)
2. I've tried adding headers manually, but I don't really know what headers i should add to make this work.
3. I have also tried accessing this API from my normal browser (Google). It returned a proper response, so it isn't an improper API key.
Also Note:
I have activated my API key, activated each of the APIs I want to use, and I have set up a billing account with Google Cloud Platform.
Not for browser
#googlemaps/google-maps-services-js is not compatible with browser environments because the Google server DOES NOT return the necessary CORS headers. This package is for Nodejs.
From the readme:
Alternative [Preferred]
Use https://developers.google.com/maps/documentation/javascript/overview.
Your code will look similar to the following:
const directionsService = new google.maps.DirectionsService();
const request = {
origin: 'Disneyland',
destination: 'Universal Studios Hollywood',
travelMode: 'DRIVING'
};
const response = await directionsService.route(request);
A directions tutorial is available.
Alternative 2
Proxy the directions endpoint through your own server and add CORS headers.
are you using cors on your endpoint?
you should allow your endpoint to respond to a different origin (this is why is Cross Origin, because it is different from the location of your endpoint).
here you can find a good/simple example of using cors policy in nodejs

I am trying to save data in database but facing error

Am creating a react app in which i am using api's for saving data to database but when i post request getting error
let responseData = await fetch('https://********************',
{method: 'post',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data)});
responseData = responseData.json();```
**error**
Access to fetch at 'https://*********************' from origin
'http://localhost:3000' has been blocked by CORS policy: Request
header field access-control-allow-origin is not
allowed by Access-Control-Allow-Headers in preflight response.
[![enter image description here][1]][1]
[1]: https://i.stack.imgur.com/kMxKF.png
It looks like you need to enable CORS on your server.
I assume from your tags that you are using Express.
You can use the cors npm package:
npm install cors
Then in your app:
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
// The rest of your app
See the docs for more advanced usage:
https://www.npmjs.com/package/cors
I hope this helps solve your problem.
are you trying to fetch directly from https://i.stack.imgur.com? That won't work as you can see in the error. Browsers don't allow making requests to hosts that are not same origin unless explicitly allowed, which in your case is localhost. You would need to run your own server in order to fetch data from other sources. If you are already running a server on localhost you should be fine. But if you are running a server on some other host, you would explicitly need to allow localhost as an exception to CORS policy. Most server frameworks have option to set that. Just google for whatever server you are using :)
You can install Moesif Orign & CORS Changer for chrome and switch to on and it will work for you

How to res.redirect to oauth url with express

I got a big problem with express.js and react. I’m trying to make google authentication via oauth2 library but I can’t get the main page redirect to auth URL from server-side. Can anyone help me out??
I've tried to send URL variable to the client but I failed, I used open (npm package) but it can't be used on lab machines where my code is.
aurl = (oAuth.generateAuthUrl({
access_type: "offline",
scope: SCOPES,
state: JSON.stringify({filename: req.file.originalname, title, description, category, audience, purpose, playlist}) }));
desc = req.body.geoloc+":"+req.body.purpose+":"+req.body.title+":"+"language"+":"+req.body.content+":"+req.body.audience+":"+req.body.detail;
res.redirect(aurl);
Then in Chrome, I get these errors:
"GET https://accounts.google.com/o/oauth2/auth?access_type=offline...
400" and "Access to XMLHttpRequest at
'https://accounts.google.com/o/oauth2/auth?access_type=offline...'
(redirected from 'http://localhost:8000/upload') from origin 'null'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.strong text

No 'Access-Control-Allow-Origin' header is present on the requested resource - VueJS

I'm developing a VueJS application which makes calls to an external API. When I do this:
this.$http.get(myAPIurl)
.then(response => {
return response.json();
})
.then(data => {
console.log(data);
});
I get these 2 errors in chrome console.
Refused to set unsafe header "Access-Control-Request-Method"
XMLHttpRequest cannot load http://xxxxxx 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:8080' is therefore not allowed access
How do I go about it?
If you are doing an XMLHttpRequest to a different domain than your page is on, your browser will block it as it usually allows a request in the same origin for security reasons. You need to do something different when you want to do a cross-domain request. A tutorial about how to achieve that is Using CORS.
When you are using postman they are not restricted by this policy. Quoted from Cross-Origin XMLHttpRequest:
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
To solve this, your external API server has to support cors request by setting following headers:
header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept');
Edited
You can use format as jsonp, like it is being done in this codepen. Here is discussion on how to use jsonp with vue-resource, see sample code from this link:
this.$http.jsonp('https://api.instagram.com/v1/tags/' + this.hash + '/media/recent', {
client_id: 'xxxxxxxxxxxxxxxxxxxxxxxx'
}, function(data){
this.pictures = _map(data.data, this.transFormInstagramModelToLocalModel);
}, {
'jsonp': 'callback'
});
You can find discussions here also helpful.

Resources