When I using axios post error pesistenly comes out. I also installed cors. I have no idea why this happening. Here is my react code.
import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import axios from 'axios'
export default function Login() {
const [Email, SetEmail] = useState('')
const [Password, SetPassword] = useState('')
return (
<div>
<h1>Login</h1>
<input type="text" placeholder="Email" value={Email} onChange={(e) => SetEmail(e.target.value)} />
<input type="password" placeholder="Password" value={Password} onChange={(e) => SetPassword(e.target.value)} />
<button type="submit" onClick={(e) => {
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const body = JSON.stringify({ Email, Password })
axios.post('http://localhost:4000/app/signin', body, config)
.then((response) => console.log(response.data))
}}>Login</button>
<div style={{ float: "right", marginTop: "10px" }}>
<Link to="/signup" style={{ color: "white" }}>
SIGN UP
</Link>
</div>
</div>
)
}
I'm practicing login. I didn't use form tag. Because when I submit data to backend, the console initialized and can't see what's happening. Next is my node.js code.
router.post(
'/signin',
[
check('email', 'Type proper e-mail').isEmail(),
check('password', 'Password is required').not().isEmpty()
],
async (request, response) => {
try{
const {email, password} = request.body;
let user = await signUpTemplateCopy.findOne({email});
const errors = validationResult(request);
if (!errors.isEmpty()) {
return response.status(401).json({errors: errors.array()});
}
if (!user){
return response.status(401).json({ msg: "There is no user with this e-mail"});
}
let isPasswordMatch = await bcryptjs.compare(password, user.password);
if (isPasswordMatch) {
const payload = {
user: {
id : user.id
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
(err, token) => {
if (err) throw err;
response.json({token});
}
)
} else return response.status(401).json({msg: "wrong password"});
} catch (error) {
console.log(error.msg);
return response.status(500).json({msg: "Server Error..."});
}
})
I can't guess even what's the problem is. Please save me from this problem.
For validating email and password I would recommend the express-validator
library. You would implement it like so:
router.post(
"/signin",
[
body("email").isEmail().withMessage("Email must be valid"),
body("password")
.trim()
.notEmpty()
.withMessage("You must supply a password"),
]
You are probably going to need an error handling middleware. The signupTemplateCopy
seems like a confusing naming convention to what should be your User
model, but you would take that instead and run an if conditional on it like so:
async (req, res) => {
const { email, password } = req.body;
const existingUser = await User.findOne({ email });
if (!existingUser) {
throw new BadRequestError("Invalid Credentials");
}
I use a little known npm library for that BadRequestError()
you see above called @dc_microurb/common@^1.0.7
. Also, instead of bcrypt
, you may also want to give scrypt
a try from the crypto
library, but what you have will work.
I am also not sure about how you are generating a JWT. Let's say you were doing it as I suggest with, const existingUser = await User.findOne({ email });
or in your case, const existingUser = await signUpTemplateCopy.findOne({ email });
, then you would take that existingUser
or in your case user
to generate the JWT like so:
const userJwt = jwt.sign(
{
id: existingUser.id,
email: existingUser.email,
},
process.env.JWT_KEY!
);
Then you need to store that JWT in a session object which I do not see anywhere in your code, like so:
req.session = {
jwt: userJwt,
};
and then you can finally send back res.status(200).send(user);
or in my example, res.status(200).send(existingUser);