Local Execution Google: https request failed - javascript

Goal
Ensure security in my request message.
Environment:
Library: Version
node-fetch : 2.6.0
https : natively implemented in node, it seems
node : 12.15.0
Device : Version
Google home nest mini : 2nd generation
Issue
I get a "Failed to fetch" error when I do get request on an api served with https and self certified certificate.
What I tried:
1 - http request: it works fine on google home device and my local machine,
2 - https request: it works on my local machine but not on google home device.
Code I use:
import fetch from 'node-fetch';
import env from './configFile';
import https, { Agent } from 'https';
export default function get(): Promise<any> {
const url = "https://api.url";
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
const option = {
method: 'get',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Basic ' + btoa(env.login! + ':' + env.password!),
},
agent: httpsAgent,
};
return fetch(url, option)
.then(res => {
return res.json();
})
.catch(error => {
throw new Error(error);
});
}
Here I disable ssl certification verification. It is something i'll change later because it is not secure, but at least i want to do an https request without error.
My Errors
Go to this link: errors
Reproduce Error
I made a full tutorial, if you want to reproduce the error: https://github.com/killvi/localExecutionHttpsError
In this tuto, i try to make an https request on google to check if I can do it without error. So is not exactly same implementation as mine. But if it works with google, at least i will known that my problem does not come from https implementation in google home device.

Google answered my question:
Currently, local execution apps can only use unencrypted HTTP/TCP/UDP to communicate locally to their devices. It has been requested that we enable TLS capabilities over the local channel to enable HTTPS and other standard encrypted transport methods.

Related

"The attempt to set cookie via Set-Cookie was blocked" with react

I am working on a small project where users authenticate using their email and password before accessing their profile. The backend uses cookies which are set when correct email and password are submitted to the auth API. I have created an instance of axios to handle the api calls and here is how it looks:
// Step-1: Create a new Axios instance with a custom config.
// The timeout is set to 10s. If the request takes longer than
// that then the request will be aborted.
const customAxios = axios.create({
...apiConfig,
timeout: 10000,
withCredentials: true,
// custom headers can be added here as shown below
// headers: { 'api-key': 'eyJz-CI6Ikp-4pWY-lhdCI6' }
});
// Step-2: Create request, response & error handlers
const requestHandler = (request) => {
request.headers["Accept"] = "application/json";
request.headers["Content-Type"] = "application/json";
return request;
};
const errorHandler = (error) => {
return Promise.reject(error);
};
customAxios.interceptors.request.use(
(request) => requestHandler(request),
(error) => errorHandler(error)
);
customAxios.interceptors.response.use(
(response) => responseHandler(response),
(error) => errorHandler(error)
);
The point is, whenever I try to call the auth API with correct credentials, it returns success but the Set-Cookie header in the response has a warning and the cookies are not set in the browser. Here is the warning:
"The attempt to set cookie using a Set-Cookie was block because it had the "SameSite=Strict" attribute but came from a cross-site response which was not the response to the top-level navigation"
Bear in mind that I am testing the API locally on port 3000 while the endpoint is deployed on a testing server using Chrome.
Thanks
Sounds like your dev setup with two different origins is the problem (and hey, your security policies are working!) Disable the SameSite=Strict in development mode, or extend it to also accept cookies from localhost:3000 (the API domain), not just the same domain where the frontend is served. Also make sure this will be disabled only in the dev setup

How to bypass CORS policy when sending get/post request from React JS?

From my React JS app , I need to fetch data from servers in other domains.
However, I am prevented by CORS policy and not able to fetch the data.
Let us assume that my React app is running on localhost:3000 during the development.
I want to make get/post call to another server running on http://myserver.com
The URL through which I want to fetch the data is http://ext-server.com/data/records?name=xyz
I have installed http-proxy-middleware thru npm and using it in my react app.
Created a setupProxy.js file under src folder with below content :
const { createProxyMiddleware} = require("http-proxy-middleware")
module.exports = app => {
app.use(
createProxyMiddleware('/data/records' , {
target:'http://ext-server.com',
changeOrigin: true
})
)
}
On the landing page of my react app (firstpage.js) when http://localhost:3000 is hit , I have added below piece of code to the button event that makes the get call to the http://ext-server.com
getTheData() {
let url = "http://ext-server.com/data/records?name=" + encodeURIComponent(this.state.name);
axios.get(url,
{
headers: {
"Content-Type":"application/json;charset=UTL-8",
"Access-Control-Allow-Origin": "*",
Accept: "application/json",
},
baseURL: 'http://ext-server.com'
}
).then((response) => {
console.log(response["access_token"]);
}).catch(error) => {
console.log("Error: ", error)
}).then(function () {
console.log("always call it")
});
}
In the package.json , I have added :
"proxy": "http://ext-server.com",
"homepage":"http://localhost:3000",
But I am still getting below error:
Access to XMLHttpRequest at 'http://ext-server.com/data/records?name= ' from origin 'http://localhost:3000' has been blocked by CORS policy.
Is there anything that I am missing here ? what is the correct way to use this http-proxy-middleware?
Any help will be very useful!
Thanks
As you can see from MDN the "Access-Control-Allow-Origin": "*" header is a response type header, this means that it should go to in your server response. Also I advise you to not use the * symbol, instead I would rather match it with the origin header in your Request.
The CORS policy is one and only administered by the web server and its settings. To allow CORS requests it has to be implemented on server side. No chance to do it from your client application.
Basically its just a header setting (below example for NodeJS):
res.header("Access-Control-Allow-Origin", "*")
Sending that header will allow requests from every domain.

How to set POST request via axios on REST API?

How to set POST request via axios on REST API?
Headers
I see that get uncorrect headers, but I don't understand, why?
Also, I often come across the fact that the documentation of the axios simply doesn't work.
Example get GET request, it works:
Dynamic host in axios
const configAxios = {
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Access-Control-Allow-Origin': '*',
},
};
const data = JSON.stringify({
cardData: this.cardData.brand,
});
axios.post('api/products', {
data,
},
configAxios,
)
.then((req) => {
this.data = req.data;
console.log(req);
})
.catch((err) => {
console.warn('error during http call', err);
});
This is necessary to get the host API:
p.s.: this will be work only in this way.
const baseURL = 'http://localhost:8080';
if (typeof baseURL !== 'undefined') {
Vue.axios.defaults.baseURL = baseURL;
}
axios version: e.g.: v0.16.2
Environment: e.g.: node v8.9.4, chrome 64.0.3282.119, Ubuntu 16.04
Symfony 4.0.4
Vue.js 2.4.2
vue-axios 2.0.2
If the API and the client are on separate domain names, you need to properly configure CORS headers to allow the client contacting the server. You also need to whitelist the authorized headers.
With API Platform and Symfony, you can easily do it using NelmioCorsBundle. If you use Symfony 4/Flex, run:
$ composer req cors
The package will be automatically installed and properly configured. `Content-Type] will even be whitelisted.

React: Axios Network Error

This is my first time using axios and I have encountered an error.
axios.get(
`http://someurl.com/page1?param1=1&param2=${param2_id}`
)
.then(function(response) {
alert();
})
.catch(function(error) {
console.log(error);
});
With the right url and parameters, when I check network requests I indeed get the right answer from my server, but when I open console I see that it didn't call the callback, but instead it caught an error.
Error: Network Error
Stack trace:
createError#http://localhost:3000/static/js/bundle.js:2188:15
handleError#http://localhost:3000/static/js/bundle.js:1717:14
If Creating an API Using NodeJS
Your Express app needs to use CORS (Cross-Origin Resource Sharing). Add the following to your server file:
// This should already be declared in your API file
var app = express();
// ADD THIS
var cors = require('cors');
app.use(cors());
For fuller understanding of CORS, please read the Mozilla Documentation on CORS.
my problem was about the url I was requesting to. I hadn't inserted http:// at the beginning of my url. I mean I was requesting to a url like 92.920.920.920/api/Token instead of http://92.920.920.920/api/Token. adding http:// solved my problem.
It happens when you work on localhost and forgot to add http://
Wrong Usage
const headers = {
"Content-Type": "application/json",
Authorization: apiKey,
};
const url = "localhost:5000/api/expenses/get-expenses";
axios.get(url, { headers });
// NETWORK ERROR
The correct one is
const headers = {
"Content-Type": "application/json",
Authorization: apiKey,
};
const url = "http://localhost:5000/api/expenses/get-expenses";
axios.get(url, { headers });
// WORKS FINE IF YOU HANDLED CORS CORRECTLY IN THE SERVER SIDE
In addition to #jacobhobson answer, I had also used some parameters to made it work.
app.use(cors({origin: true, credentials: true}));
I was having same issue on production on digital ocean droplet. I was using axios in ReactJS to call Node.js API.
Although I included cors
const cors = require('cors');
app.use(cors());
But I still had to add
res.header( "Access-Control-Allow-Origin" );
before calling out my controller. And it worked for me. There I realized that cors is not working properly. So I uninstalled and installed them again and It Works!
Complete code is here.
So either you use
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.header("Access-Control-Allow-Headers", "x-access-token, Origin, X-Requested-With, Content-Type, Accept");
next();
});
or use
app.use(cors());
It's the same.
I received a network error with axios 0.27.2 when I was trying to upload an image to our server. After I set headers like below no error is received.
headers:{"Accept":"application/json, text/plain, /","Content-Type": "multipart/form-data"}
and you need to check with your api request's body type in your collection like if it's form-data or x-wwww-form-urlencoded or ..etc.
Make sure you have the same port number in cors({ origin : [ "http://localhost:3001"]}) and the .env file.
In my case I used "https" instead of "http", check that too.
I just want to let you know that after searching for a solution for two days, I was able to solve my error.
Since the proxy was the source of the issue, I must configure a proxy in the package.json file, and I have to follow these instructions in the function that uses Axios:
try { await axios.post("user/login", formData).then((res) => { console.log(res.data); }); } catch (error) { console.log(error.response.data.message); }
and in package.json file need to add a proxy:
"proxy": "http://localhost:6000",
for better understand check this documentation: enter link description here
If you are running react native in development while using real device connected via USB(and the API server is being accessed via development machine IP), ensure the development machine and the device are both connected to the same network
This is happening because of restrict-origin-when-cross-origin policy.Browser sends a pre-flight request to know whom the API server wants to share the resources.
So you have to set origin there in API server and send some status.After that the browser allow to send the request to the API server.
Here is the code.I am running front-end on localhost:8000 and api server is running on port 6000.
const cors = require("cors");
app.options("*", cors({ origin: 'http://localhost:8000', optionsSuccessStatus: 200 }));
app.use(cors({ origin: "http://localhost:8000", optionsSuccessStatus: 200 }));
I have set origin as my front-end url, If You set it to true , then it will allow only port 8000 to access rosource, and front-end running on port 8000 can not access this resource. Use this middleware before route in api server.
I have resolved my issue by adding this header.
var data = new FormData();
data.append('request', 'CompaniesData');
var config = {
method: 'post',
url: baseUrl, headers:{"Accept":"application/json, text/plain, /","Content-Type": "multipart/form-data"},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
i'm using axios in react-native as android and .net as backend, i have same issue but i can't solve the problem. I think it is security problem when i type the url in chrome it warns me about that in emulator.
axios("http://10.0.2.2:5001/api/Users/getall")
.then((result) => setUsers(result.data.data))
.then((json) => {
return json.data;
})
.catch((error) => {
console.error(error);
})
.then((response) => response.parse());
In my case, I'm using Hapi.js as the backend, so all I had to do is set the cors value to true as in the code below;
const server = Hapi.server({
port: 4000,
host: 'localhost',
state: {
strictHeader: false
},
routes: {
cors: true
}
});
change the port number of your node server.
It took more than 3 hours to solve this error. Solution ended with changing port numer which was initially set to 6000, later set to 3001. Then it worked. My server localhost base url was:
"http://localhost:6000/data"
I changed port number in app.listen() on server and from frontend I call that GET route in async function as
await axios.get('http://localhost:3001/data').
It is working fine now.
If you face the address issue: address already in use :::#port
Then on command prompt: killall -9 node

CORS issue with ASP.net Identity

I am working on an angular.js project with one of my friends, and we are running into a specific CORS (cross origin request) issue. The server is a Microsoft ASP.NET restful API, and I am using angular.js with Node.js.
We enabled CORS on the server side, and are able to get responses for everything else, accept the user login, which we are using ASP.NET Identity with. We always get the same error which I will post bellow, as well as the POST from the Client side. So basically my question is, does any one have an idea on how to fix this? Thanks!
XMLHttpRequest cannot load http://lectioserver.azurewebsites.net/api/v1/accounts/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost' is therefore not allowed access. The response had HTTP status code 400.
function login(username, password) {
var innerconfig = {
url: baseUrl + "/api/v1/accounts/login",
data: {
username: username,
password: password,
grant_type: "password"
},
method: "POST",
headers:
{
'Accept': 'text/json'
}
};
return $http(innerconfig).then(onSuccess, requestFailed);
function onSuccess(results) {
if (results && results.data) {
$rootScope.access_token = results.data.access_token;
return results.data;
}
return null;
}
}
Try to set the content-type in the headers, this might fix the issue
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
This usually happens because app that provides you token starts before CORS initiates.
Fixing it is very easy. You just need to go to IdentityConfig.cs and inside that there is function called as
public static ApplicationUserManager Create
(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
Insert this following line of code there
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "*" });
This will enable CORS for Token request.
But problem is when we do this other normal requests will start throwing error since we have granted access origin * twice. Once in identiy and other in cors.
if you run into this error use this if statement on cors code in identity config you just pasted.
if(context.Request.ContentType == "text/plain")

Categories

Resources