ElectronJS Vue Axios Basic Authentication Access-Control-Allow-Origin error - javascript

I have been googling the all of the interwebs and I just can't find the solution to my problem. I'm trying to make an application using ElectronJS and I need to send an HTTP request with authentication basic header but I just can't get it to work.
Here's my code:
export default {
name: 'home',
data: function() {
return {token: ''}
},
methods: {
fetchData() {
this.$http({
method: 'get',
url: 'URL_TO_SERVER',
auth: {
username: 'USERNAME',
password: 'PASSWORD'
},
headers: {
'Access-Control-Allow-Origin': '*',
credentials: 'same-origin',
},
withCredentials: true,
}).then((response) => {
console.log(response.data);
}).catch((error) => {
console.log('ERROR: '+ error.response.data);
});
}
}
}
I am getting the following error:
XMLHttpRequest cannot load (URL_TO_SERVER). 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:9080' is therefore not allowed access. The response had HTTP status code 401.
Does anyone have any idea's what could be my next step to fixing this?
If i do the same info with a REST client it will return the correct values, just not in ElectronJS

After building the application in to an EXE, it worked, just doesnt work in npm run dev.

Related

How do I make a post request from a react front-end to a node back-end? Getting 404

I'm trying to make a simple website where users can post things to learn the MEAN stack. When I'm handling the POST request, which will be handled and inputed to the MongoDB server through the back-end. React is on port 3000, and the server is on 5000. How do I make the request go from 3000 to 5000? My request works through Postman but not using axios. I added the proxy to the client-side package.json.
I've tried changing the proxy, adding CORS, changing to every single possible route. Nothing works.
Back-end:
router.post('/api/req',(req,res)=>{
const newPost = new Post({
title: req.body.title,
description: req.body.description
})
newPost.save().then(()=>{
console.log('Item added to database!')
});
})
Front-end:
axios({
method: 'post',
url: '/api/req',
data: {
title: this.state.title
},
validateStatus: (status) => {
return true;
},
}).catch(error => {
console.log(error);
}).then(response => {
console.log(response);
});
"proxy": "http://localhost:5000/" - package.json
I'm expecting the POST request to go through, and for the title to be inputed into the database. Instead, I get the error: Failed to load resource: the server responded with a status of 404 (Not Found)
The error is coming from localhost:3000/api/req, and it should be proxying port 5000. Also, the actual route is routes/api/req.js.
You will have to pass the complete url:
axios({
method: 'post',
url: 'http://example.com:5000/api/req',
data: {
title: this.state.title
},
validateStatus: (status) => {
return true;
},
}).catch(error => {
console.log(error);
}).then(response => {
console.log(response);
});

API call working through server side code (node.js, php) but not through JS in browser using fetch()

I am trying to make an API POST request via fetch(). When I execute it server side ( PHP or Node.js ) it works properly. When trying to execute it in the browser I get two errors:
1) 405 Error - Method not allowed
2) Access to fetch at 'url' from origin 'null' 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.
I have tried adding: mode: "no-cors". I then get the following error:
"401 Unauthorized"
with the following response:
401 response
Here is my standard js setup:
const TrailData = {
email: "test#test.com",
first_name: "sample string 5",
last_name: "sample string 6",
phone2: "12121212"
};
// TRAIL POST ( NOT WORKING )
fetch('http://webapi.mymarketing.co.il/api/contacts', {
method: "POST",
mode: 'no-cors',
headers: {
"Authorization": "API CODE //here comes the API CODE",
"Content-Type": "application/json"
},
body: JSON.stringify(TrailData)
})
.then(res => console.log(res) )
.then(data => console.log(data))
.catch(err => console.log(err))
My Node js setup is:
var postData = {
sms_status: "None",
email: "test#test.com",
first_name: "sample string 5",
last_name: "sample string 6",
};
let axiosConfig = {
headers: {
"Authorization": "API CODE",
'Content-Type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Origin": "*",
}
};
const Trail = async () =>{
try {
const response = await axios.post('http://webapi.mymarketing.co.il/api/contacts', postData, axiosConfig)
console.log(response)
} catch (error) {
throw new Error(error)
}
}
Trail()
Node JS works. I get a 200 OK response. The first one doesnt!
Is it possible that the API blocks requests made from the browser?
I have tried so many ways and failed every time using the browser.
Thank you for any help!
you can't send extra headers without CORS (Authorization header)
because server does not respond to preflight request you are not allowed to send that request
without CORS you are allowed to send only "Simple requests" see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests
see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
and https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
for more information

How to fix CORS error when posting form from client to AWS API gateway function?

I have a contact form on my front end react application that I want to post to an Lambda function that is behind a API Gateway which in turn has a custom domain on top of it.
My front end runs on domain dev.example.com:3000
My API Gateway is on contact.example.com
Further more, I have created my Lambda function with serverless and in my YAML file, have enabled CORS as so:
# serverless.yml
service: contact-form-api
custom:
secrets: ${file(secrets.json)}
provider:
name: aws
runtime: nodejs8.10
stage: ${self:custom.secrets.NODE_ENV}
region: us-east-1
environment:
NODE_ENV: ${self:custom.secrets.NODE_ENV}
EMAIL: ${self:custom.secrets.EMAIL}
DOMAIN: ${self:custom.secrets.DOMAIN}
iamRoleStatements:
- Effect: "Allow"
Action:
- "ses:SendEmail"
Resource: "*"
functions:
send:
handler: handler.send
events:
- http:
path: email/send
method: post
cors: true
I am using AXIOS to make my post request which happens client side:
const data = await axios.post(
"https://contact.example.com/email/send",
formData,
{
"Content-Type": "application/json",
}
)
And the error I get is:
Access to XMLHttpRequest at 'https://contact.example.com/email/send' from origin 'http://dev.example.com:3000' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains the invalid value 'example.com'.
I would have thought having the front end and API on the same domain would get around any cors errors (although I am spoofing dev.example.com) locally in order to test). I would also think the cors setting in my YAML file would get around it.
Anybody know why I might still be getting this CORS error?
Edit: Showing handler code that runs in Lambda function
// handler.js
const aws = require('aws-sdk')
const ses = new aws.SES()
const myEmail = process.env.EMAIL
const myDomain = process.env.DOMAIN
function generateResponse (code, payload) {
return {
statusCode: code,
headers: {
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'x-requested-with',
'Access-Control-Allow-Credentials': true
},
body: JSON.stringify(payload)
}
}
function generateError (code, err) {
console.log(err)
return {
statusCode: code,
headers: {
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'x-requested-with',
'Access-Control-Allow-Credentials': true
},
body: JSON.stringify(err.message)
}
}
function generateEmailParams (body) {
const { email, name, content } = JSON.parse(body)
console.log(email, name, content)
if (!(email && name && content)) {
throw new Error('Missing parameters! Make sure to add parameters \'email\', \'name\', \'content\'.')
}
return {
Source: myEmail,
Destination: { ToAddresses: [myEmail] },
ReplyToAddresses: [email],
Message: {
Body: {
Text: {
Charset: 'UTF-8',
Data: `Message sent from email ${email} by ${name} \nContent: ${content}`
}
},
Subject: {
Charset: 'UTF-8',
Data: `You received a message from ${myDomain}!`
}
}
}
}
module.exports.send = async (event) => {
try {
const emailParams = generateEmailParams(event.body)
const data = await ses.sendEmail(emailParams).promise()
return generateResponse(200, data)
} catch (err) {
return generateError(500, err)
}
}
You should add an HTTP request header as 'Content-type':
Now, go to Integration requests, and change the mapping template as follows:
Hope, it helps. and don't forgot to deploy the API before testing.

Vue.js Fetch throws 404 and api response

I can't make a POST request in Vue.js. It was giving me CORS issues, but I added
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, DELETE");
to the API and they went away. I can get valid responses from the API using Postman while using the same email and password (Postman ignores CORS).
Here is my Fetch request:
<script>
export default {
data () {
return {}
},
methods : {
login : function () {
console.log('Logging in');
// axios({
// method : 'post',
// url : 'https://www.example.com/login',
// headers : {'content' : 'application/json'},
// data : {
// email : 'emailHere',
// password : 'passwordHere'
// }
// })
// .then(function (response) {
// console.log(response);
// })
// .catch(function (error) {
// console.log(error);
// });
fetch('https://www.example.com/login', {
method: 'POST',
body: JSON.stringify({
email : 'emailHere',
password : 'passwordHere'
})
})
.then((res) => res.json())
.then((data) => console.log(data))
.catch((err) => console.error(err))
}
}
}
</script>
https://www.example.com/api/v1/authenticate/login 404 (Not Found)
{status: false, message: "Invalid credentials"}
I tried Axios, and still gives me 404, but not the "Invalid Credentials" response.
In other applications I have used jquerys ajax successfully with the same API, so the API seems to allow javascript requests. But Fetch and Axios don't like it.
I have a Login.vue component that has a button
<a id="login-btn" #click.prevent="login">{{ $t('loginPage.loginButtonText') }}</a>
Any help would be appreciated! Thanks!
You are missing Content-Type header. Try setting headers in your request. Fetch demands that you set headers explicitly since it is a low-level API. Your server may reject as it doesn't recognize appropriate Content-Type. Try this:
fetch('https://www.example.com/login', {
method: 'POST',
// THIS IS IMPORTANT
headers: new Headers({
'Content-Type': 'application/json',
'Accept': 'application/json',
}),
body: JSON.stringify({
email : 'emailHere',
password : 'passwordHere'
})
})
Also, remember two things with fetch:
First getting 404 using fetch doesn't mean that your request has failed. If a server responds 4xx or 5xx error, then fetch is considered successful. Only when a network error occurs, fetch is rejected. So if you get 404, it means the request has reached server but there is a problem with the client side.
Second, try setting mode to cors in you fetch request. Thought the default value of mode is cors.

Still getting a 503 error when making API calls in my React app

I am trying to get my React-Redux app to communicate to my deployed Heroku API via Axios.
When I try to make a POST request to my Heroku server via Axios I get this error message in my console in the Chrome developer tools:
As you can see in the screencap, I am getting "No 'Access-Control-Allow-Origin' header is present on the requested resource." as well as error status code of 503.
And something I find rather odd is that my /register request is being fired twice. Is that normal?
Here is the configuration in my app.js file in my backend code to enable cross domain requests:
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", '*');
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
res.header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Origin,X-Auth,X-Requested-With,Content-Type,Accept,content-type,application/json,x-auth,Access-Control-Request-Method,Access-Control-Request-Headers");
next();
});
And here is the Axios code that makes the API call to the server in my front-end:
import axios from 'axios'
export function register(fields) {
console.log('below are the fields');
console.log(fields);
return function action(dispatch) {
let objArrSkills = Object.keys(fields.form_skills);
let skillsArr = objArrSkills.map(function (value) {
if (fields.form_skills[value] === true && fields.form_skills[value] !== undefined) {
return value;
}
});
let objArrArts = Object.keys(fields.form_arts);
let artsArr = objArrArts.map(function (value) {
if (fields.form_arts[value] === true && fields.form_arts[value] !== undefined) {
return value;
}
});
console.log('artsArr is...' + artsArr);
console.log('skillsArs is...' + skillsArr);
const request = axios({
method: 'post',
url: "https://jammr-backend.herokuapp.com/register",
data: {
firstName: fields.form_first_name,
lastName: fields.form_last_name,
email: fields.form_email,
password: fields.form_password,
skills: skillsArr,
iWantToMake: artsArr,
street: fields.form_address,
city: fields.form_city,
provinceState: fields.form_province,
gender: fields.form_gender,
imLookingFor: ['Acting', 'Drawing', 'Music', 'Writing', 'Programming', 'Videography']
},
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': "Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Origin,X-Auth,X-Requested-With,Content-Type,Accept,content-type,application/json,x-auth,Access-Control-Request-Method,Access-Control-Request-Headers",
'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE,PATCH,OPTIONS'
}
});
return request.then(response => {
console.log('axios call ran! Below is response....');
console.log(response);
dispatch({
type: 'REGISTER',
payload: {
myId: response.data,
fields: fields,
skills: skillsArr,
iWantToMake: artsArr
}
})
},
err => {
if (err) throw err;
})
}
};
Is there anything wrong with my code? Here is my front-end and back-end code on Github.
And in case it's relevant, my backend is deployed on Heroku. Also, I did try using the cors npm package, but it didn't work.
I would be willing to bet you are getting the 503 from the heroku stack because of some issue with your backend. (A timeout perhaps?) Obviously, the Heroku stack is not going to add the cross origin headers which is why you are seeing the cross origin errors in the JS console. Can you perhaps post your server logs?

Categories

Resources