Sending data from react server to node server - node.js

I am trying to send the data from input boxes in react server to nodejs server but everytime i am getting error on backend
TypeError: Cannot read property 'email' of undefined
Here is my code for that
onformsubmit=()=>{
console.log(this.state.email,this.state.password) ///gets printed correctly
axios.post('http://localhost:5000/acc-details',{
email:this.state.email,
password:this.state.password
})
.then(response=>{
console.log('success')
})
.catch(err=>console.log(err))
}
and then in node server
const express=require('express')
const app=express()
var bodyparser=require('body-parser')
app.use(bodyparser.json())
router.post('/acc-details',(req,res)=>{
console.log(req.body.email)
res.send('ok')
})
if not consoling in node server i am getting response back 'ok' as writtten above but i want to fetch my email and password on node server for db authentication

Modify your Axios request slightly to send multipart/form-data data.
onformsubmit = () => {
// Collect properties from the state
const {email, password} = this.state;
// Use FormData API
var formdata = new FormData();
formdata.append('email', email);
formdata.append('password', password);
axios.post('http://localhost:5000/acc-details', formdata)
.then( response=> {
console.log('success')
})
.catch(err=>console.log(err))
}

onformsubmit=()=>{
console.log(this.state.email,this.state.password) ///gets printed correctly
axios({
url: 'http://localhost:5000/acc-details'
method: 'POST',
data: { email: this.state.email, password: this.state.password }
})
.then(response=>{
console.log('success')
})
.catch(err=>console.log(err))
}
Now you should be able to access req.body
Edit:
after 200 tries, i figured out:
axios({
url: "http://localhost:5000/acc-details",
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
},
data: { email: this.state.email, password: this.state.password }
});```

Related

Cookie token sent by server but not stored in browser

I have this code in node js API :
const jwt = require("jsonwebtoken");
generateToken = (user, res) => {
const token = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, {
expiresIn: "1800s",
});
res
.cookie("token", token, {
httpOnly: true,
})
.status(200)
.json({ message: "Logged in successfully 😊 👌" });
};
module.exports = generateToken;
I have this code in Next js project :
const onSubmitLogin = (data) => {
axios
.post(
`http://localhost:8000/login`,
{
email: data.email,
password: data.password,
},
{
headers: {
"Content-Type": "application/json; charset=UTF-8",
},
}
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
If I use Postman, i get the cookie with the token.
But, when I use the browser I dont get the cookie stored in cookies.
I tried to add withCredentials: true, in axios request but nothing changes.
However, I get the message "Logged in successfully 😊 👌" in the browser's console

Axios don't answer me after post request

I have an issue regarding Axios in my React project, Nodejs. During my Post request my request arrives at my back end but i can't have the Axios response. I try to reply with Status Code but nothing comes to my front. For info, I have a proxy in the package.json of my Front.
Here the part in my Front:
await axios({
method: 'post',
url: "http://localhost:5000/api/user/register",
data: {
username,
email,
password,
},
proxy: {
protocol: 'http',
host: 'localhost',
port: 5000,
}}).then(function (res) {
console.log(res);
console.log(res.data);
console.log(res.errors);
})
}};
Here is my Back end file:
module.exports.signUp = async (req, res) => {
const { username, password, email } = req.body;
try {
const existUsername = await User.findOne({username: username});
if(existUsername){
res.status(404);
console.log('premiere partie du if');
} else {
console.log('je suis dans le else');
const user = new User({ username: username, email: email });
await user.setPassword(password);
await user.save();
res.status(200);
}
} catch (err) {
console.log(err);
res.redirect("/api/user/register");
}
};
I have no answer with Axios. So I can't handle my mistakes. If someone has an idea. Thank you
You need to put res.send() to send back an empty body, or else Express won't send anything back.

How to handle login with MongoDB through REST API?

I'm not sure how to check if the values match with the MongoDB data. I am using PUT and trying to use findOneAndUpdate to check if the values match.
<script>
const logindetails = new Vue({
el: '#logindetails',
data: {
email: "",
password: "",
on: Boolean
},
methods: {
login: function (e) {
e.preventDefault();
const log = {
email: this.email,
password: this.password,
}
const options = {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(log)
};
fetch('http://localhost:3000/users/${this.email}/${this.password}',
options).then(response => {
[...]
</script>
This is the server code (it successfully connected to MongoDB) :
app.put('/students/:email/:password', (req, res, next) => {
console.log("login");
res.setHeader("Content-Type", "application/json");
db.collection('users').findOne({email: (req.params.email), password: (req.params.password)},
{$set: {on: true}})
.then(results => res.send(results))
.catch(err => res.send(err))
});
I personally don't think it is a good idea to put your username and password as query string, because it hurts the restful api convention. It wouldn't make sense to use a put request if there is no body being pass. Also, a post request would make more sense in a login situation .Anyway I digress, here are the usual steps to doing authentication.
1. (Client-Side) Send the email and password in the body of the fetch request
//something like this
const body = { email, password };
const response = await fetch(
"http://localhost:5000/authentication/login",
{
method: "POST",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(body)
}
);
2.(Server-Side - make sure you to use app.use(express.json()) to access req.body)
//defining middleware to access req.body
app.use(express.json());
app.post("/authentication/login", async(req,res) =>{
//1. destructure email and password
const {email, password} = req.body
//2. check if user doesn't exist
const user = await db.user.find({user_email: email})
if(!user){
return res.status(401).send("User does not exist");
}
//3. Check if password is the same as the password in the database
if(password !== user.password){
return res.status(401).send("Wrong Credential")
}
//4. This is up to you when the user is authenticated
res.json(`Welcome back ${email}`);
})

JSON webtoken login authorisation for react and express protected routes

I am struggling to make a login system using JSON web tokens.
I have made the login (client side) that calls to my server.js file.
This is the login through the client side Below is my handle submit function that calls the server.js login route.How would I use a token here?
handleSubmit(e) {
e.preventDefault();
if (this.state.email.length < 8 || this.state.password.length < 8) {
alert(`please enter the form correctly `);
} else {
const data = { email: this.state.email, password: this.state.password };
fetch("/login", {
method: "POST", // or 'PUT'
headers: {
Accept: "application/json, text/plain, */*",
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
}
}
catch(e) {
console.log(e);
}
This is the login route for my server.js. As you can see I have assigned a jwt but how would I send this back to my login form and utilise it for protected routes.
app.post("/login", async (req, response) => {
try {
await sql.connect(config);
var request = new sql.Request();
var Email = req.body.email;
var Password = req.body.password;
console.log({ Email, Password });
request.input("Email", sql.VarChar, Email);
request.input("Password", sql.VarChar, Password);
const result = await request.execute("dbo.LoginUser");
if (result.recordsets[0].length > 0) {
console.info("/login: login successful..");
console.log(req.body);
const token = jwt.sign({ user: Email }, "SECRET_KEY", {
expiresIn: 3600000
});
var decoded = jwt.verify(token, "SECRET_KEY");
console.log(decoded);
response.status(200).json({
ok: true,
user: Email,
token: token
});
console.log(token);
} else {
console.info("/login: bad creds");
response.status(400).send("Incorrect email and/or Password!");
}
} catch (err) {
console.log("Err: ", err);
response.status(500).send("Check api console.log for the error");
}
});
Essentially all I want is for my submit handler to be called for login. Server returns a jwt token which can then be used to verify other routes.
There are two ways to route:
Use React-Redux and react-router.
Save the fetched JWT token into localStorage and use to validate route within your routes component.
I would recommend in using React-Redux / React-router for protected routing.
Here is a video link to Build Real Web App with React by
Rem Zolotykh
This will help you.

Back-end API receiving empty request body when making request from front-end

I am building Web application on my localhost.
The front-end is Reactjs framework, running in localhost:3000
The back-end is nodejs + Express, running in localhost:4000
Now, I have created the API below:
router.post('/register', function (req, res) {
console.log(req.body); // {}, why it is empty?
// create new instance, save it to database
User.create(req.body).then(function () {
res.send('success');
});
});
The front-end part is:
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values); // value is not empty, I have tested! So we did send something to the API
const input = JSON.stringify({
username: values.username,
password: values.password,
});
console.log(input);
$.ajax({
url: `${API_ROOT}/register`,
method: 'POST',
data: JSON.stringify({
username: values.username,
password: values.password,
}),
}).then((response) => {
if (response === 'success') {
this.props.history.push('/login');
} else {
console.log('do not jump');
}
});
}
});
}
I have tested the API by the postman, I can add users to MongoDB, so the API is good.
I have console.log what I sent to API, it is not empty, however, backend API receive d empty request body. I have already fixed the "Access-Control-Allow-Origin" issue, so I think I do send something to the API, but backend API received empty request body.
If you add a content type header saying what type the body of the request is it should work as expected.
$.ajax({
url: `${API_ROOT}/register`,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
data: JSON.stringify({
username: values.username,
password: values.password,
})
})

Resources