Preflight response is not successful. Status code: 403. React, Flask and Stripe? - reactjs

I feel like I've looked everywhere for this and can't find my answer!
I've got a React app working with a Node server, but I need to get it to work with a Flask server instead.
This is my React code:
function buy() {
window.scroll(0, 0);
fetch(`${IP}/init_checkout`, {
method: "POST",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: 'my_stripe_product_price',
}),
})
.then(res => {
if (res.ok)
return res.json();
return res.json().then(json => Promise.reject(json));
})
.then(({ url }) => {
window.location = url;
})
.catch(e => {
console.error(e.error);
});
}
And, my route in Flask:
#app.route('/init_checkout', methods=['POST'])
#cross_origin(origin="*")
def init_checkout():
data = json.loads(request.data)
price_id = data['price_id']
try:
checkout_session = stripe.checkout.Session.create(
success_url='http://localhost:3000', # noqa
cancel_url='http://localhost:3000/form',
payment_method_types=[
'card', 'sepa_debit', 'sofort', 'ideal'
],
mode='subscription',
line_items=[{
'price': price_id,
'quantity': 1
}],
)
return redirect(checkout_session.url, code=303)
except Exception as e:
print(str(e))
return jsonify({'error': {'message': str(e)}}), 400
In the console, I get the url I'd like to get too, but the app won't automatically direct me there?

Just for reference in case anyone else comes across this or similar ... thanks to hmunoz:
function buy() {
window.scroll(0, 0);
fetch(`${IP}/init_checkout`, {
method: "POST",
headers: {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json",
},
body: JSON.stringify({
price_id: 'my_stripe_product_price',
}),
})
.then(res => {
if (res.ok)
return res.json();
return res.json().then(json => Promise.reject(json));
})
.then(({ url }) => {
window.location = url;
})
.catch(e => {
console.error(e.error);
});
}
And, my route in Flask:
#app.route('/init_checkout', methods=['POST'])
#cross_origin(origin="*")
def init_checkout():
data = json.loads(request.data)
price_id = data['price_id']
try:
checkout_session = stripe.checkout.Session.create(
success_url='http://localhost:3000', # noqa
cancel_url='http://localhost:3000/form',
payment_method_types=[
'card', 'sepa_debit', 'sofort', 'ideal'
],
mode='subscription',
line_items=[{
'price': price_id,
'quantity': 1
}],
)
return checkout_session
except Exception as e:
print(str(e))
return jsonify({'error': {'message': str(e)}}), 400

Related

Cors with api in react [duplicate]

This question already has answers here:
No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
(26 answers)
Closed 3 months ago.
I'm making a simple currency converter, and I can't overcome the error:
picture with error
Here is a part of code:
try {
const { data } = await axios.get(
'https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5',
{
method: 'POST',
mode: 'no-cors',
headers: {
Accept: 'application/json',
WithCredentials: true,
'Access-Control-Allow-Origin': 'http://localhost:3000/',
'Content-Type': 'application/json; charset=UTF-8',
'Access-Control-Allow-Methods': 'OPTIONS,GET,POST,PUT,DELETE',
'Access-Control-Allow-Headers':
'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With',
Authorization: '',
},
withCredentials: true,
credentials: 'same-origin',
}
)
data.push({ ccy: 'UAH', buy: '1', sale: '1' })
data.splice(2, 1)
return data
} catch (error) {
alert(error)
}
}
Help please :)
tried many solutions from google but to no avail...
The problem can be solved by using proxies
The proxy I have used in this example is allOrigins which is a free and opensource proxy
Using Axios, (You can change url with whatevery url you want)
try {
const url = "https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5";
const { data } = await axios.get(
`https://api.allorigins.win/raw?url=${encodeURIComponent(url)}`
);
data.push({ ccy: "UAH", buy: "1", sale: "1" });
data.splice(2, 1);
return data;
} catch (error) {
alert(error);
}
Using Fetch api, (You can change url with whatevery url you want)
try {
const url = "https://api.privatbank.ua/p24api/pubinfo?json&exchange&coursid=5";
const data = await fetch(
`https://api.allorigins.win/raw?url=${encodeURIComponent(url)}`
)
.then((response) => response.json())
.then((data) => data);
data.push({ ccy: "UAH", buy: "1", sale: "1" });
data.splice(2, 1);
return data;
} catch (error) {
alert(error);
}

What link do I call to Amazon s3 when I use axios

I'm new to S3 so I didn't find anywhere in the API where it says that this is the respective URL to use for the axios URL parameter. I'm keeping on getting a 404 error saying that the
axios({
url: `call/s3/backend`,
method: "post",
data: {
//images: imageArray.toByteArray(),
},
})
.then((res) => {
//imageUrlArr = res.data;
axios({
url: `api/petition_posts`,
method: "post",
data: {
petition_post: {
title: title,
description: description,
hashtags: arrayOfHashtags.join(" "),
amount_donated: 0,
//media: imageUrlArr,
goal: money,
card_type: "petition",
org_profile_id: 1,
},
},
})
.then((res) => {
console.log(res.data);
})
.catch((error) => console.log(error));
})
.catch((error) => console.log(error));
}
titleError(true ? title.length === 0 : false);
descriptionError(true ? description.length === 0 : false);
};
To upload a file from the browser to S3 using Axios:
fetch a pre-signed S3 URL from your server
PUT the file to the pre-signed URL using Axios
Server:
const aws = require('aws-sdk')
aws.config.update({
accessKeyId: '...',
secretAccessKey: '...'
})
const s3 = new aws.S3()
const params = {
Bucket: 'my-bucket',
Key: 'my-file.txt',
Expires: 300,
ContentType: 'text/plain'
}
s3.getSignedUrl('putObject', params,
(error, signedUrl) => return signedUrl /* to client */ )
Client:
const axios = require('axios')
axios.put(<signed-url-from-server>, 'abc', {
headers: {
'Content-Type': 'text/plain'
}
}).then(res => console.info(res))
.catch(err => console.error(err))

Upload image in react native

I have want to upload an image but I seem to be getting network request error.
sample values
{"name": "IMG20200427083924.jpg", "type": "image/jpeg", "uri": "content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F240735/ORIGINAL/NONE/image%2Fjpeg/158476572"}.
Am I doing this right?
export const uploadDocumentAction = (profpic) => {
console.log(Endpoint.UPLOAD_DOCUMENT_URL)
return async (dispatch) => {
dispatch(uploadDocument());
try {
let body = new FormData();
body.append('document', { uri: profpic.uri, name: profpic.filename, type: profpic.type });
await AsyncStorage.getItem('accessToken', (error, accessToken) => {
fetch(Endpoint.UPLOAD_DOCUMENT_URL, {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
Authorization: `Bearer ${accessToken}`
},
body: body
})
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson)
dispatch(uploadDocumentSuccess(responseJson));
})
.catch((error) => {
console.log('error', error);
dispatch(uploadDocumentFailed())
})
});
} catch (error) {
console.log(error);
dispatch(uploadDocumentFailed('Internal Server Error'))
}
}
}

axios.post returns bad request of 400 React Native

I'm getting my token from an API but unfortunately my API is returning 400 bad request. I've already checked my api via Postman and it's working fine there. Kindly let me know solution or any mistake.
async componentWillMount(){
axios.post('http://api.myapiurl.com/token', {
grant_type: 'PASSWORD',
username: 'MY_USERNAME',
password: 'MY_PASSWORD'
}, {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).then(response => {
console.log(response.data)
}).catch(err => console.log("api Erorr: ", err.message))
}
error in response below
Request failed with status code 400
- node_modules\axios\lib\core\createError.js:16:24 in createError
- node_modules\axios\lib\core\settle.js:18:6 in settle
- ... 10 more stack frames from framework internals
It is Solved by using QueryString.stringify(). I just pass the body into QueryString.stringify() like below:
axios.post('http://api.apiurl.com/token', QueryString.stringify({
grant_type: 'MY_GRANT_TYPE',
username: 'MY_USERNAME',
password: 'MY_PASSWORD'
}), {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
}
}).then(response => {
console.log(response.data)
}).catch(err => console.log("api Erorr: ", err.response))
From what I can see you are sending json data, but your Content-Type header is set to application/x-www-form-urlencoded; charset=UTF-8. if your api is expecting json then it should be application/json.
try using fetch instead, might be some axios bug, you dont need to add any libraries, here is an example:
fetch("http://api.myapiurl.com/token", {
method: "POST", // *GET, POST, PUT, DELETE, etc.
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
grant_type: "PASSWORD",
username: "MY_USERNAME",
password: "MY_PASSWORD"
})
})
.then(res => {
res.json();
})
.then(data => console.log(data)) // ur data is here
.catch(err => console.log("api Erorr: ", err));
First install the package axios from the url https://www.npmjs.com/package/react-native-axios
Then create two service for handling get and post request so that you can reuse them
GetService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const GetService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.get(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
PostService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const PostService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.post(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
Sample code for using get and post services is given below
import { PostService } from './PostService';
import { GetService } from './GetService';
let uploadData = new FormData();
uploadData.append('key1', this.state.value1);
uploadData.append('key2', this.state.value2);
//uploadData.append('uploads', { type: data.mime, uri: data.path, name: "samples" });
let jwtKey = ''; // Authentication key can be added here
PostService(uploadData, 'postUser.php', jwtKey).then((resp) => {
this.setState({ uploading: false });
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
GetService({}, 'getUser.php?uid='+uid, jwtKey).then((resp) => {
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
Reference from one of my another post Post action API with object parameter within the URL
If you have any doubts, feel free to know

Api call works on postman but Doenst work on my code

So I have to update some user info ,it works fine on postman but when I try to type it in react-native I must be doing something wrong in the body of the fetch method. In postman I set x-www-form-urlencoded and type the keys like this :
Key ----- Value
moto ----- test
and that seems to work,but when I try to do the same on my code I somehow fail at it,here is my code
updateUser(){
return fetch(url,{
method: "PATCH",
headers: {
"X-Auth-Token": bearerToken,
"Content-Type":"application/x-www-form-urlencoded"
},
body: JSON.stringify({
moto: this.state.moto
}
})
}
)
I get 200 response which means the call works but I must be seting the parameter moto wrong somehow.
Any ideas ?
"Content-Type":"application/x-www-form-urlencoded"
should be
"Content-Type":"application/json"
form-urlencoded is way different from your body: JSON.stringify().
You'll want to use a FormData object instead:
const body = new FormData();
body.append('moto', this.state.moto);
fetch(url, {
method: "PATCH",
headers: {
"X-Auth-Token": bearerToken,
"Content-Type": "application/x-www-form-urlencoded"
},
body,
})
APICall = () => {
fetch(‘Your http URL’, {
method: 'PATCH',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
‘X-Auth-Token’: bearerToken,
},
body: JSON.stringify({
moto: this.state.moto
})
}).then((response) => response.json())
.then((responseJson) => {
if(responseJson.statuscode == 1) {
Alert.alert('Success');
} else {
Alert.alert(responseJson.message);
}
}).catch((error) => {
console.error(error);
});
}
finally fixed it by seting body to
body:
`moto=${this.state.moto}`
it appears that urlencoded headers require parameters in the form of
parameter1=value1&parameter2=value2
componentDidMount() {
return fetch(“Your URL”, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"Authorization": “token”
},
body: "firstName=Nikhil&favColor=blue&password=easytoguess"
})
.then((response) => response.json())
.then(function (data) {
alert(“Success”)
console.log('Request succeeded with JSON response', data);
})
.catch(function (error) {
alert("error occur")
console.log('Request failed', error);
});
}
const formData = new FormData();
formData.append('email', 'test#gmail.com');
formData.append('password', '123456');
fetch("https://test.com/api/login", {
method: 'post',
body: formData
})
.then(res => res.json())
.then(
(result) => {
console.log(result);
}).catch(err => {
console.log(err);
})

Resources