React fetch post, page refreshing and becomes a GET request - javascript

I have a login page in my REACT website sending a POST request with fetch, but every time the request is submitted for some reason it refreshes the page and send it as a GET request, here's the method on my login page:
onSubmitSignIn = () => {
fetch("http://192.168.56.1:8560/signin", {
type: 'POST',
headers: {'Accept': 'application/json',
'Content-Type': 'application/json'},
body: JSON.stringify({
email: this.state.signinEmail,
password: this.state.signinPassword,
}),
})
.then(response => response.json())
.then(data => {
if (data ==='success'){
}
})
}
the server side signing page is as follows:
app.post('/signin', (req, res) => {
if (req.body.email === database.users[0].email && req.body.password === database.users[0].password){
res.json("success");
}else{
res.status(404).json("Error loggingin");
}
})
It's working fine with Postman, the server seems to be ok.
I have tried changing HTTP to https even though my server is HTTP just in case.
Tried restarting both servers, tried changing to fetch to axios but nothing seems to be working.
Any thoughts?

onSubmitSignIn = (event) => {
event.preventDefault() // <= You Need this
fetch("http://192.168.56.1:8560/signin", {
type: 'POST',
headers: {'Accept': 'application/json',
'Content-Type': 'application/json'},
body: JSON.stringify({
email: this.state.signinEmail,
password: this.state.signinPassword,
}),
})
.then(response => response.json())
.then(data => {
if (data ==='success'){
}
})
}

Create-React-App Proxying API Requests in Development -- src/setupProxy.js
People often serve the front-end React app from the same host and port as their backend implementation.
Such setup is not required. However, if you do have a setup like this, it is convenient to write requests like fetch('/api/todos') without worrying about redirecting them to another host or port during development.
To tell the development server to proxy any unknown requests to your API server in development, add a proxy field to your package.json, for example:
"proxy": "http://localhost:8560",
Configuring the Proxy Manually
First, install http-proxy-middleware using npm or Yarn:
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
Next, create src/setupProxy.js and place the following contents in it:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8560',
changeOrigin: true,
})
);
};
API:
https://create-react-app.dev/docs/proxying-api-requests-in-development/

I'm just replying in case anybody has got the same issue as I was having, after a couple of sleepless nights digging through my code, I figure the template for my login page was taken from a "tachyon" template, what I missed, somewhere in my version control, was a "form" that was actually supposed to be turned into a "div", after going through this question here why-the-post-request-becomes-a-get-request it hit me, basically, if you happen to be taking the information from inside of a "form" and this form does not have a method post, it will automatically turn the API request into a GET request and fill up the URL with the information.
So that is sorted. Now let us tackle the rest of the bugs.

Related

Prevent Man in The Middle Attack

So I have a React Native App where a user can register. React Native uses the normal JavaScript Fetch API:
fetch("http://myip:8000/api/account/register/", {
method: "POST",
headers: {
"Accept": 'application/json',
"Content-Type": "application/json"
},
body: JSON.stringify({
username: username,
password: password,
email: email
})
})
.then(response => {
return response.json()
})
.then(data => {
afterRegister(data)
}
.catch(error => {
console.log(error)
}
})
The problem is, that I also could make a POST request from e.g. POSTMAN :/ I thought about a security code, that I need to add to the body (hardcoded) that only the Client, who has the code could make a POST request. A code like this could look like this: Dhiuw1298md()AJM8d9j289j)N ASIDH)8zh2n1ujD)(AZwh98em9812z)(ZDM)("ZM)8mdwuJio2h1hn398 and so on...
But now if I do this and a user register in the App he/she also could use a man in the middle attack to fetch the code and the spam POST requests to the Server until the Server crashes.
How can I prevent, that the user can see the content of the HTTPS POST Request with a man in the middle attack?
I also could make a POST request from e.g. POSTMAN :/
[…] spam POST requests to the Server until the Server crashes.
A code is only useful for authentication, i.e. identifying which user is sending the request to your server (and it's no good if the code is shared across all users, i.e. basically public). It doesn't help against a DoS attack - that's what a firewall is good for.

Why can I not authenticate with the GitHub REST API using Axios?

I'm sort of new to REST..
For full disclosure, I'm running this code inside of a Netlify Lambda function and testing via netlify-lambda.
My curl command works:
curl -u "<username>:<password>" https://api.github.com/repos/<username>/<reponame>
But when I attempt a get request via axios I'm getting a 404 (which according to github docs implies an auth issue). This is what I'm doing (also doesn't work without the custom headers, I've just been trying random things).
axios({
method: "get",
url: `https://api.github.com/repos/${user}/<reponame>/`,
headers: {
Authorization: `Bearer ${githubToken}`,
"Content-Type": "application/json"
},
auth: {
username: user,
password: pass
}
})
.then(res => {
callback(null, {
statusCode: 200,
body: JSON.stringify(res.data)
});
})
.catch(err => {
callback(err);
});
One thing I noticed was that it seems axios was taking my username and password and prepending them to the url i.g. https://<username>:<password>#api.github.com/repos/<username>/<reponame>
Is this how auth should be sent over?
I shouldn't have had a trailing forward slash at the end of my URL.
If you already have a token you don’t need user/pass, just add the token to the header.

Difference between Fetch and Axios

can somebody explain to me why when I am using fetch and accessed my nodejs api - it is authorized but when I tried using axios to access my api - it is unauthorized.
This is the code I am using in fetch (It came from tutorial: https://medium.com/#alexanderleon/implement-social-authentication-with-react-restful-api-9b44f4714fa) Bec I am studying his way of authenticating using passport-facebook-token.
(client -->(login fbsdk)--> fb --> (access token)--> client -->(pass access token)--> nodejs api --> (get credentials) --> passport-fb-token --> (send credentials) --> nodejs api --> (credentials)--> client)
const tokenBlob = new Blob([JSON.stringify({access_token: response.accessToken}, null, 2)], {type : 'application/json'});
const options = {
method: 'POST',
body: tokenBlob,
mode: 'cors',
cache: 'default'
};
fetch('http://localhost:4000/api/v1/auth/facebook', options).then(r => {
const token = r.headers.get('x-auth-token');
r.json().then(user => {
if (token) {
this.setState({isAuthenticated: true, user, token})
}
});
})
This is the code of my axios
axios({
method: 'post',
url: 'http://localhost:4000/api/v1/auth/facebook',
headers: {
'Access-Control-Allow-Origin': '*',
},
data: {
access_token: response.access_token
}
})
.then((res) => console.log(res))
.catch((err) => console.log(err));
You should configure axios to use your token in one central place. For example
export const configureAxios = (token) => {
axios.interceptors.request.use(req => {
// don't give our token to non-our servers
if (isDomesticRequest(req.url)) {
req.headers.Authorization = `Bearer ${token}`;
}
return req;
});
}
This blog should help you get your answer in detail:
Fetch vs. Axios.js for making http requests
Axios is a Javascript library used to make http requests from node.js
or XMLHttpRequests from the browser and it supports the Promise API
that is native to JS ES6. Another feature that it has over .fetch() is
that it performs automatic transforms of JSON data.
If you use .fetch() there is a two-step process when handing JSON
data. The first is to make the actual request and then the second is
to call the .json() method on the response.
The .fetch() method is a great step in the right direction of getting
http requests native in ES6, but just know that if you use it there
are a couple of gotchas that might be better handled by third-party
libraries like Axios.

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 Native Post Request via Fetch throws Network Request Failed

I've came across the following error.
At the moment I developing an Android App with React Native therefore I'm planning to use fetch for doing a post request for me.
fetch("https://XXreachable-domainXX.de/api/test", {
method: "post",
body: JSON.stringify({
param: 'param',
param1: 'param',
})
})
.then((response) = > response.json())
.then((responseData) = > {
ToastAndroid.show(
"Response Body -> " + JSON.stringify(responseData.message), ToastAndroid.SHORT
)
})
.catch((error) = > {
console.warn(error);
});
The app now throws an error:
TypeError: Network request failed
When I change the code to a GET-Request it's working fine, in the browser with a window.alert() as a return it's cool and also the Chrome extension Postman returns data correctly.
Developing with Windows OS/PHP built-in server/react-native Android on device:
check server local IP address (ipconfig), e.g. 172.16.0.10
in react-native fetch use this URL and proper port (fetch('http://172.16.0.10:8000/api/foo))
run PHP built-in server with this specific IP instead of the localhost: php -S 172.16.0.10:8000 ...
turn off Windows firewall for the private networks
That fixed the connection problem between Android phone and the local server for me.
This React Native's error is rather useless, so you need to get the actual underlying error first. The most straightforward way is to write a small native program that would just perform the same query using HttpsURLConnection.
For me the actual error was java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
which has a well known solution: https://developer.android.com/training/articles/security-ssl.html#MissingCa
This is quite likely your case also, given that the browsers and Postman have no problem with the request. To check it run openssl s_client -connect XXreachable-domainXX.de:443 -showcerts. If there are certificate errors, fix them first, it could spare you time writing the native program.
Edit: actually the easiest way to see all underlying android errors for react native is simply running 'adb logcat' in terminal
None of the other answers helped me.
The problem was headers:
Old header:
fetch(API_HOST, {
method: 'POST',
headers: {
Accept: 'application/json'
},
body: JSON.stringify(data),
Updated header:
fetch(config.API_HOST, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json' // I added this line
},
body: JSON.stringify(data),
If you have had this error and you are sure everything works well and you are running an emulator, simply close your emulator and fire it up again.
It should run now.
This usually happens after you have hibernated your system for a while
step1>
add android:usesCleartextTraffic="true" line in AndroidManifest.xml like:
// add this line
...
step2>
Delete all debug folder from your android folder..
I had a major issue doing the same on the android emulator. On iOS approving the domain in the info.plist was necessary. To be clear I was attempting to login to my .NET web hosted API.
The fix was to make sure the post data was parameterised.( I'm pretty sure that's a word)
export const loginUser = ({ userName, password }) => {
const data = `UserName=${userName}&Password=${password}&grant_type=password`
return (dispatch) => {
dispatch({ type: LOGIN_USER })
fetch(URL_LOGIN, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: data
// body: {
// UserName: userName,
// Password: password,
// grant_type: 'password'
// }
})
.then((response) => {
loginUserSuccess(dispatch, response)
})
.catch((response) => {
loginUserFailed(dispatch, response)
})
};
};
If you run into this problem on emulator make sure you also test it on the device. It's most probably not happening there.
Just so you know there's nothing to worry about if you can work around it.
I had this problem on Android due to an expired certificate. The error message I had was com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at Fri Sep 29 16:33:39 EDT 2017 (compared to Fri Dec 08 14:10:58 EST 2017).
I was able to confirm this using digicert.com.
Unfortunately I did have to dig rather deep into the React Native code and debug the XHR code in the bundle (index.android.bundle) in order to find the error message and the URL in question, because it was in some of my logging code, which I obviously didn't log to the console as well. :)
I was helped by this GitHub issue comment.
My issue was fixed when I restarted the emulator
I had same issue using the fetch,this is a type error.so try using Axios. This worked for me.
the code which wasnt working :error:[typeError : network Request failed]
return fetch(addProduceApi, { method: 'PATCH', body: bodyParamData, headers: getAuthHeader() })
.then((response: any) => response.json()) .catch((error: any) => console.log('Error in patchProduce: ', error));
the working code:
return axios.patch(addProduceApi,produceData,{ headers: getAuthHeader()})
.then((response: any) => response.json()) .catch((error: any) => console.log('Error in patchProduce: ', error));?
Check two cases bellow
Wrong end-point
Internet connection: both real-device, virtual-device
It has eaten 2 hour with the second reason.

Categories

Resources