So i have a react app which if someone is logged in will check for it's account level and based on that will enable or disable features. It worked until it was all localhost, but now i have a server in the cloud and the request is pending forever. Other requests to the same endpoint works fine. I tried changing the address to localhost, but then it looks for the API server on my PC. It's strange because the same endpoint works with other requests. This single request also works on localhost but not if i use server's IP. Here's an image of the Network page of Chrome development tools: https://i.ibb.co/c2r8Js1/Screenshot-at-2019-12-27-15-11-41.png
getLoggedLevel = () => {
var URL = process.env.REACT_APP_API_URL;
var URL2 = 'http://localhost:8000/requests'
axios({
url: URL,
method: 'post',
data: {
message: 'getLoggedLevel',
username: JSON.parse(localStorage.getItem('loggedUser')).username
}
}).then(res => {
this.setState({loggedLevel: res.data.level})
})
}
Edit: I created a separate endpoint for that single request, and it's 404 however in firefox it's 200 for OPTIONS... Now i'm really confused :(
Related
when I run the following code from the client side in javascript as the coinbase cloud documentation says https://docs.cloud.coinbase.com/exchange/reference/exchangerestapi_getcoinbaseaccounts
const options = {
method: 'GET',
headers: {
Accept: 'application/json',
'cb-access-key': 'Apikey',
'cb-access-passphrase': 'Mypassphrase',
'cb-access-sign': cb_access_sign,
'cb-access-timestamp': cb_access_timestamp
}
};
fetch('https://api.exchange.coinbase.com/coinbase-accounts', options)
.then(response => response.json())
.then(response => console.log(response))
.catch(err => console.error(err));
when I do it with axios the same thing happens
the following error appears in console: "Access to fetch at 'https://api.exchange.coinbase.com/coinbase-accounts' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field cb-access-passphrase is not allowed by Access-Control-Allow-Headers in preflight response."
what am I doing wrong?
You can't do this in the browser, you need to do it from the web server. You can either display the data when the page loads or use vue/react and write your own interaction with the webserver.
edit: doing this in the browser makes your keys visible...
Coinbase API has misconfigured CORS (or intentionally require you to make API calls from a server). Regardless, this makes it very hard to test in a dev environment. This can be solved using a proxy. This can be configured using cors-anywhere which changes the api call flow from:
Client (localhost:3000) <-> Coinbase API (api.exchange.coinbase.com)
to
Client (localhost:3000) <-> Proxy Server (www.your-proxy-server.com) <-> Coinbase API (api.exchange.coinbase.com)
In summary, coinbase will only see a request coming from your proxy server and does not care/know where the proxy server sends back the data. Cors-anywhere will also include the headers and data along with the request.
Do not use public cor-anywhere servers unless you are quickly testing something. It is best to set up your own.
Using Firebase
I used cors-server to set mine up using firebase functions. You want your Firebase functions to look like the following:
const {onRequest} = require("firebase-functions/v2/https");
const corsAnywhere = require('cors-anywhere');
const cors = require("cors")({origin:true})
const corsServer = corsAnywhere.createServer({
originWhitelist: [
'http://localhost:3000',
],
requireHeader: ['origin', 'x-requested-with'],
removeHeaders: ['cookie', 'cookie2'],
});
exports.proxy = onRequest((request, response) => {
cors(request,response,() =>{
corsServer.emit('request', request, response);
})
});
and an example of a request in your client code
return(
axios({
url: `https://proxy-your-function-id.a.run.app/https://api.exchange.coinbase.com/profiles`,
headers: await getHeaders(options),
method: 'GET',
data: options.body
}).then((response)=>{
return(response)
}).catch((err)=>{
return(err.response)
})
)
Edit: It should also be noted that Coinbase is getting rid of Coinbase Pro and its API end of 2022. Coinbase exchange and its API will still be available at https://api.exchange.coinbase.com however Pro users will be merged into Advanced Trading on their main platform which uses oAuth to link the API (or standard keys for personal projects).
I have a running Vue.js application that request to the server.
My client-side application is running on e.g. cms.abc.com and the server in ApiGee running on this dns server.abc.com
The request code using axios is
const headers = {
'x-api-key': 'xxxxx123123'
}
return axios({
method: get,
url: 'server.abc.com/items',
headers: headers
}).then(response => {
console.log(respnose.data)
})
When I check the browser network I'm getting status 401 Unauthorized during OPTIONS request.
The APIgee CORS has been enabled, but when I check the logs from the ApiGee the value for x-api-key is missing.
I'm also not sure why my client side application is still sending OPTIONS request. I'm expecting that it should skip the CORS since the client and the server are having the same origin. which is abc.com
This question has been asked a million times, but I've tried it all and nothing seems to work.
My situation:
I've deployed a node/express backend as a Google Cloud Run service.
I am running my frontend locally, trying to login to my backend in the cloud. Frontend is served on http, backend on https. I have enabled cors on the backend. My config is:
app.use(cors({
origin: 'http://localhost:3000',
credentials: true,
}));
I am using axios, and I have set withCredentials: true:
axios.defaults.baseURL = ApiURL;
const { data } = await axios({
method: 'post',
url: `/api/login`,
data: {
username: this.state.username,
password: this.state.password,
keepLoggedIn: this.state.keepLoggedIn,
},
withCredentials: true,
});
This setup works perfectly when I run my backend locally, but of course there is no cors then. When I try to log in when the frontend is pointed at the Cloud Run service, I get a response from the backend with a set-cookie header as expected, but no cookie ever appears in the Storage > Cookies section of the Chrome dev console as it does with my local backend. There is then of course nothing sent with the rest of my axios requests, which need the cookie.
I've been at this for a full day and its driving me nuts. I'm sure there is something simple I'm missing. Any ideas?
I saw several posts on the subject but without result. I have on the one hand a form which collects information (name, first name etc) then saves it in database (mongodb). Everything works when I use postman to send my information via the route / signup, i can see my new user in mongodb. but when i'm starting the app on Expo he throw me "Network request failed".
Frontend fetch :
submitForm = () => {
var signupData = JSON.stringify({
first_name: this.state.firstName,
last_name: this.state.lastName,
email: this.state.email,
password: this.state.password
});
fetch(`https://localhost:3000/signup`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: signupData
})
.then(response => {
console.log(response);
return response.json();
})
.then(data => {
if (data.result) {
this.props.handleUserValid(
this.state.firstName,
this.state.lastName,
this.state.email,
data.user.token
);
this.props.navigation.navigate("Account");
}
})
.catch(error => {
console.error(error);
});
};
And Backend route :
router.post("/signup", function(req, res, next) {
var salt = uid2(32);
console.log("Signup is running...");
const newUser = new userModel({
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: SHA256(req.body.password + salt).toString(encBase64),
token: uid2(32),
salt: salt
});
newUser.save(function(error, user) {
console.log("LOG: user", user);
res.json({ result: true, user });
});
});
module.exports = router;
And here is a screenshot of the error
Again when using Postman, the fetch is working good, my console log is printed and the user added to my data base.
Thanks for the help.
-- EDIT --
I launched the application in a web browser via Expo and everything works perfectly. My sign in / sign up pages and my account page. But on my phone it's not working (IOS), it's a network problem from my phone (maybe a certificate problem, wrong IP ?)
if you have an idea i'm interested, i've been stuck on it for 2 days
Had the same issue with React-native Expo and Python Django back-end.
The problem is about a conflict between an emulator localhost and server localhost.
Your back-end-server might be ruunning on 127.0.0.1:8000, but an emulator can't find this.
In terminal find your Ipv4-Address with a command 'ipconfig'.
For ex., it will be 192.138.1.40
After this put it into your fetch (
'http://192.138.1.40:8000/').
And what is also important - run your back-end-server with the same host and port.
On python Django for example:
py manage.py runserver 192.138.1.40:8000
On Django you will also need to add ALLOWED_HOSTS = ['192.138.1.40'] in settings.py
Instead of 'localhost', while using expo, use your device's (computer's) IP address (http://192.168.x.x:3000/'signup'). This method worked for me. Make sure that your PC and mobile are connected to the same network. Type ipconfig/all in the command prompt to find IP address.
Update:
Seems like this was my problem coupled with my roommates hogging the wifi bandwidth. Slow internet connection may also be a problem. ATB with your problem.
I had the same issue with Expo: fetch error. For my backend. I use json-server to mock API data. In my case, the json-server runs on http://localhost:3000/playlist
Instead of fetch("http://localhost:3000/playlist"), I did fetch(http://10.0.2.2:3000/playlist), then it worked. Using the Android emulator, it could not find the server's address.
For the reason why using 10.0.2.2, check here. why do we use 10.0.2.2 to connect to local web server instead of using computer ip address in android client
I had the same issue - what worked for me was to:
Run my local server on host 0.0.0.0
Go to network preferences and find my LAN IP address (e.g. 192.168.1.1)
Replace the host in my url in the mobile app with the LAN IP (e.g. http://192.168.1.1:3000/signup)
Reload and test
For anyone using Serverless, I used this command to run on 0.0.0.0
ENV=local serverless offline -s local -o 0.0.0.0
I had a similar issue. Apparently, the emulator does not understand or see 'localhost' as host.
What I did:
run ipconfig on your cmd, copy the ipv4 address, then use that to replace 'localhost' for your server host.
you should check the URL
https://localhost:3000/signup (X)
http://localhost:3000/signup (O)
NOT HTTPS
If anyone facing this issue with a hosted backend server this is for your knowledge.
Used react native expo cli
Backend(Spring Boot) hosted on a Azure server ( Eg URL : https://abcd-spring-app.azurewebsites.net). HTTPS used.
But still I faced the below issue.
Network request failed at node_modules\whatwg-fetch\dist\fetch.umd.js:535:17 in setTimeout$argument_0
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:130:14 in _callTimer
at node_modules\react-native\Libraries\Core\Timers\JSTimers.js:383:16 in callTimers
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:416:4 in __callFunction
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:109:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:364:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:108:4 in callFunctionReturnFlushedQueue
After some research I found that this is because the slow response time of the server. The network request failed due to the timeout.
So Before testing your app with the backend server, send some requests from the web(or any other way) and up your server. Because some servers get inactive after some time. Make sure you have a good connection.
I have a user authentication server setup using Express and Node.js in my localhost Port 3333 and I am trying to connect to the endpoint in Next.js port 3000 using isomorphic-unfetch for the fetch. I am getting a CORS 401 error, I have done a fair bit of research already but just wanted to know whether it was possible connecting to a Express server on localhosts? I have tried adding "Access-Control-Allow-Origin": "*", "Content-Type": "multipart/form-data" to a header object. The express server has cors setup already.
This function below is called on click of a button.
onLoginClick = async () => {
let header = new Headers({
"Access-Control-Allow-Origin": "*",
"Content-Type": "multipart/form-data"
});
const res = await fetch("http://localhost:3333", {
method: "POST",
header,
body: JSON.stringify({
username: "USER",
password: "PASSWORD"
})
});
}
Error message -
http://localhost:3333/ 401 (Unauthorized)
Response {type: "cors", url: "http://localhost:3333/", redirected: false, status: 401, ok: false, …}
First of all, CORS is configured on the server side. You configure your server to allow calls from specific origins.
In your code, onLoginClick is a client-side code, it runs on the browser, client cannot decide which origin the server should allowed to, that would defeat the purpose of having CORS.
Usually you don't need to change the cors configuration in a Next.js app, because you would be calling the API from the same origin that hosted the client side app.
By default, Next.js only support same-origin for API Routes, if you need to customize it, you can use micro-cors.