I want to use my own API to check the information about email and password, but I don't know how to do that. Anything information that I put show up "Login" but I need to just show up "Login" if the information was the same that I registered in my database.
import { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import { Link } from "react-router-dom"
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
const info = {email, password}
fetch('http://localhost:3333/login/', {
mode: 'no-cors',
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(info)
}).then((response) => {
console.log(response)
console.log("login")
}).catch(() => {
console.log("NO")
})
}
return (
<div className="all ">
<div className='button d-flex justify-content-center '>
<Link to="/" className="text-center btn btn-secondary btn-lg m-4">Login</Link>
<Link to="/register" className="text-center btn btn-secondary btn-lg m-4">Register</Link>
</div>
<p className='text-center'>Sign With:</p>
<div className="container d-flex justify-content-center">
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email" value = {email} onChange={(e) => setEmail (e.target.value)} placeholder="Enter email" required/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" value = {password} onChange={e => setPassword(e.target.value)} placeholder="Password" />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicCheckbox">
<Form.Check type="checkbox" label="Check me out" />
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
</div>
);
}
export default Login;
My API is shown below and it's working fine and the login function is verifying well
const {
PrismaClient
} = require("#prisma/client");
const prisma = new PrismaClient();
const bcrypt = require('bcrypt');
module.exports = {
async createUser(req, res) {
try {
const {
firstName,
lastName,
email,
password,
age,
role
} = req.body
const salt = await bcrypt.genSalt();
console.log(salt)
const hash = await bcrypt.hash(password, salt)
console.log(hash)
const verifyemail = await prisma.UserInfo.findUnique({
where: {
email
}
})
if (verifyemail) {
return res.json({
error: "there is a email with the same name, please change."
})
}
const user = await prisma.UserInfo.create({
data: {
firstName: firstName,
lastName: lastName,
email: email,
password: hash,
age: age,
role: role
}
});
return res.json(user)
} catch (error) {
return res.json({
error
})
}
},
async login(req, res) {
try {
const {email, password} = req.body
const user = await prisma.UserInfo.findUnique({
where: {
email : req.body.email
}
})
if(user) {
const match = await bcrypt.compare(password, user.password)
if(match) {
return res.send("login")
}
else {
return res.send("There is something wrong with your password")
}
}
} catch (error) {
return res.json({
error
})
}
}
}
What I have understood from your question is that, no matter what username and password you are entering you are always ending up in the .then block, while if the username/password is wrong it should go to the catch block.
If I have understood that correctly, I would suggest updating your node code to handle this scenario. Fetch will only go in catch if there is a network error or CORS error, check this
With this, I would suggest you can add an else block in your Node code and add
return res.status(401).send("Icorrect password");
after this, in front end code, you can add
.then(response => /* check response status code and throw 'Incorrect' if 401 */ )
Related
I'm trying to consume but I've been receiving an error:
{error: {…}}
error
:
{clientVersion: '4.9.0'} but my api is working. I can't consume it on front-end
I put many console logs when I submit and the result is
{firstName: 'Matheus', lastName: 'Coppi', role: 'enginner', age: '23', email: 'matheus#gmail', …}
Response {type: 'cors', url: 'http://localhost:8080/register', redirected: false, status: 200, ok: true, …}
{error: {…}}
error: {clientVersion: '4.9.0'}
The error is my catch from my api
async createUser(req, res) {
try {
const {
firstName,
lastName,
role,
age,
email,
password
} = req.body
const salt = await bcrypt.genSalt();
console.log(salt)
const hash = await bcrypt.hash(password, salt)
console.log(hash)
const verifyemail = await prisma.UserInfo.findUnique({
where: {
email
}
})
if (verifyemail) {
return res.send({
"error": "true"
})
}
const user = await prisma.UserInfo.create({
data: {
firstName: firstName,
lastName: lastName,
role: role,
age: age,
email: email,
password: hash
}
});
return res.send(user)
} catch (error) {
return res.json({ error }) // The error client version is from here
}
}
Here is my react front-end
import { useState } from 'react';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
const Register = () => {
const [firstName, setFirstName] = useState('')
const [lastName, setlastName] = useState('')
const [role, setRole] = useState('')
const [age, setAge] = useState('')
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
const info = {firstName, lastName, role, age, email, password}
console.log(info)
fetch("http://localhost:8080/register", {
method: 'POST',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(info)
}).then(async response => {
console.log(response) //until here it works
try {
const data = await response.json()
console.log(data)
} catch(error) {
console.log('Error happened here!')
console.error(error)
}
})
}
return (
<div className='all1'>
<div className="container d-flex justify-content-center">
<Form onSubmit={handleSubmit}>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>First Name</Form.Label>
<Form.Control type="text" placeholder="First Name" value={firstName} onChange={(e) => setFirstName(e.target.value)}/>
<Form.Label>Last Name</Form.Label>
<Form.Control type="text" placeholder="Last Name" value={lastName} onChange={(e) => setlastName(e.target.value)} />
<Form.Label>Role</Form.Label>
<Form.Control type="text" placeholder="role" value={role} onChange={(e) => setRole(e.target.value)}/>
<Form.Label>Age</Form.Label>
<Form.Control type="number" placeholder="age" value={age} onChange={(e) => setAge(e.target.value)}/>
<Form.Label>Email address</Form.Label>
<Form.Control type="email" placeholder="Enter email" value={email} onChange={(e) => setEmail(e.target.value)}/>
<Form.Text className="text-muted">
We'll never share your email with anyone else.
</Form.Text>
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password" placeholder="Password" value={password} onChange={(e) => setPassword(e.target.value)}/>
</Form.Group>
<Button variant="primary" type="submit">
Submit
</Button>
</Form>
</div>
<div>{email}</div>
<div>{password}</div>
</div>
);
}
export default Register;
I want to make a login page. But the problem is that even though the data I entered is wrong, it redirects to the page. how can i fix this?
I only have email and password information in my table
const client = require('../../db')
const express = require('express');
const app = express();
const cors = require("cors");
app.use(cors());
app.use(express.json()); //req.body
app.listen(2121, ()=>{
console.log("Sever is now listening at port 5000");
})
client.connect();
app.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
const user = await client.query(
`SELECT * FROM users WHERE email=$1 AND password=$2`,
[email, password]
);
if (user.rows.length === 0) {
res.send("Kullanıcı adı veya şifre yanlış");
} else {
res.send("Kullanıcı adı veya şifre doğru");// Eşleşen kullanıcı bilgileri varsa diğer sayfaya yönlendir
}
} catch (err) {
console.error(err.message);
}
});
this is my database code.when i run my database query in postman it works correctly
import React, { useState } from 'react'
import Navbar from '../../common/Navbar/Navbar';
const User = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [user, setUser] = useState([]);
const [error, setError] = useState('');
const onSubmitForm = async e => {
e.preventDefault();
try {
const response = await fetch(`http://localhost:2120/login`,{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (response.ok) {
window.location.replace(`/AdminPage.js`);
} else {
setError('Invalid email or password');
}
} catch (err) {
console.error(error);
setError('An error occurred. Please try again later.');
}
};
return (
<>
<Navbar/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.4.1/dist/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"></link>
<div className="container text-center">
<h1 className="my-5">Search for the Dormitory You Want</h1>
<form className="d-flex" onSubmit={onSubmitForm}>
<input
type="text"
name="name"
placeholder="Enter email ..."
className="form-control"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<input
type="text"
name="name"
placeholder="Enter password ..."
className="form-control"
value={password}
onChange={e => setPassword(e.target.value)}
/>
<button className="btn btn-success">Submit</button>
</form>
</div>
</>
)
}
export default User
this is my login page code.
The issue is related backend side since when you are sending the wrong login and password, you are still responding as a 200 ok. By default the HTTP status code sent in a response from an Express application is 200 (OK). Instead of that, you can just throw an error message with 404 status. In addition, if there is another issue that is not related correction of credentials you may to response 500 status code as an internal error. I have added inside catch.
app.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
const user = await client.query(
`SELECT * FROM users WHERE email=$1 AND password=$2`,
[email, password]
);
if (user.rows.length === 0) {
res.status(404).send("Kullanıcı adı veya şifre yanlış");
} else {
res.send("Kullanıcı adı veya şifre doğru");// Eşleşen kullanıcı bilgileri varsa diğer sayfaya yönlendir
}
} catch (err) {
response
.status(500)
.json({ message: "Error in invocation of API: /login" })
}
});
I am building a nodejs, reactjs app and i am having issues for making requests from my reactjs part of the app to my API. I am using concurrently, so i made a proxy:
"proxy":"http://localhost:5000/"
Port 5000 is where my API is running and Port 3000 is where my ReactJs runs.
When i try to register a new user i get the following error
Cannot POST api/users
And my console shows what url is trying to request http://localhost:3000/api/users
But instead it should be http://localhost:5000/api/users
This is my Register.js:
import React, { Fragment, useState } from 'react'
import axios, { Axios } from 'axios';
const Register = () => {
const [formData, setFormData] = useState({
name:'',
email: '',
password: '',
password2: ''
});
const { name, email, password, password2 } = formData;
const onChange = e => setFormData({
...formData, [e.target.name]:e.target.value
});
const onSubmit = async e => {
e.preventDefault();
if(password !== password2){
console.log('Passwords do not match')
} else {
const newUser = {
name,
email,
password
}
try {
const config = {
headers:{
'Content-type': 'application/json'
}
}
const body = JSON.stringify(newUser)
const res = await axios.post('api/users', body, config);
console.log(res.data);
} catch (error) {
console.error(error.response.data)
}
}
}
return (
<Fragment>
<section className='container'>
<h1 className="large text-primary">Sign Up</h1>
<p className="lead"><i className="fas fa-user"></i> Create Your Account</p>
<form className="form" action="create-profile.html" onSubmit={e => onSubmit(e)}>
<div className="form-group">
<input type="text"
placeholder="Name"
name="name"
value={name}
onChange={e => onChange(e)}
required />
</div>
<div className="form-group">
<input type="email"
placeholder="Email Address"
name="email" value={email}
onChange={e => onChange(e)}
required/>
<small className="form-text"
>This site uses Gravatar so if you want a profile image, use a
Gravatar email</small
>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
name="password"
minLength="6"
value={password}
onChange={e => onChange(e)}
required
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
name="password2"
minLength="6"
value={password2}
onChange={e => onChange(e)}
required
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
Already have an account? Sign In
</p>
</section>
</Fragment>
)
}
export default Register
And this is my users.js
//#route POST api/users
//#desc Register user
//#access public
router.post('/', [
check('name', 'Name is required')
.not()
.isEmpty(),
check('email', 'Plese include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
],
async (req, res)=> {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
}
const { name, email, password } = req.body;
try{
//See if user exists
let user = await User.findOne({ email });
if(user){
return res.status(400).json({ errors: [{ msg:'User already exists' }] });
}
//Get users gravatar
const avatar = gravatar.url(email,{
s:'200',
r:'pg',
d:'mm'
})
user = new User({
name,
email,
avatar,
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken -> this for users to be logged in right after registration
const payload = {
user:{
id: user.id
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
{expiresIn: 360000}, //change to 3600 for production
(err, token)=>{
if(err) throw err;
res.json({ token });
}
)
}catch(err){
console.error('err.message');
res.status(500).send('Server Error');
}
});
module.exports = router;
What am i doing wrong? What is the solution to this error?
I am devloping a webapp with nodejs and reactjs with redux. I am trying to make a request to register a new user but i am getting a bad request.
This is the error i am getting:
POST http://localhost:5000/api/users 400 bad request
This is my users route:
const express = require('express');
const config = require('config');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { check , validationResult } = require('express-validator/');
const User = require('../../models/User');
//#route POST api/users
//#desc Register user
//#access public
router.post('/', [
check('name', 'Name is required')
.not()
.isEmpty(),
check('email', 'Plese include a valid email').isEmail(),
check('password', 'Please enter a password with 6 or more characters').isLength({min:6})
],
async (req, res)=> {
const errors = validationResult(req);
if(!errors.isEmpty()){
return res.status(400).json({ errors:errors.array()}); //400 is for bad requests
}
const { name, email, password } = req.body;
try{
//See if user exists
let user = await User.findOne({ email });
if(user){
return res.status(400).json({ errors: [{ msg:'User already exists' }] });
}
//Get users gravatar
const avatar = gravatar.url(email,{
s:'200',
r:'pg',
d:'mm'
})
user = new User({
name,
email,
avatar,
password
});
//Encrypt password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
await user.save();
//Return jsonwebtoken -> this for users to be logged in right after registration
const payload = {
user:{
id: user.id
}
}
jwt.sign(
payload,
config.get('jwtSecret'),
{expiresIn: 360000}, //change to 3600 for production
(err, token)=>{
if(err) throw err;
res.json({ token });
}
)
}catch(err){
console.error('err.message');
res.status(500).send('Server Error');
}
});
module.exports = router;
The route is not the problem i think because if i register manually a user via postman it works.
This is my register.js component:
import React, { useState } from 'react';
import { connect } from 'react-redux';
import { Link, Navigate } from 'react-router-dom';
import { setAlert } from '../../actions/alert';
import { register } from '../../actions/auth';
import PropTypes from 'prop-types';
const Register = ({ setAlert, register }) => {
const [formData, setFormData] = useState({
name: '',
email: '',
password: '',
password2: ''
});
const { name, email, password, password2 } = formData;
const onChange = (e) =>
setFormData({ ...formData, [e.target.name]: e.target.value });
const onSubmit = async (e) => {
e.preventDefault();
if (password !== password2) {
setAlert('Passwords do not match', 'danger');
} else {
register({ name, email, password });
console.log('SUCCESS')
}
};
return (
<section className="container">
<h1 className="large text-primary">Sign Up</h1>
<p className="lead">
<i className="fas fa-user" /> Create Your Account
</p>
<form className="form" onSubmit={onSubmit}>
<div className="form-group">
<input
type="text"
placeholder="Name"
name="name"
value={name}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="email"
placeholder="Email Address"
name="email"
value={email}
onChange={onChange}
/>
<small className="form-text">
This site uses Gravatar so if you want a profile image, use a
Gravatar email
</small>
</div>
<div className="form-group">
<input
type="password"
placeholder="Password"
name="password"
value={password}
onChange={onChange}
/>
</div>
<div className="form-group">
<input
type="password"
placeholder="Confirm Password"
name="password2"
value={password2}
onChange={onChange}
/>
</div>
<input type="submit" className="btn btn-primary" value="Register" />
</form>
<p className="my-1">
Already have an account? <Link to="/login">Sign In</Link>
</p>
</section>
);
};
Register.propTypes = {
setAlert: PropTypes.func.isRequired,
register: PropTypes.func.isRequired
};
export default connect( null, { setAlert , register })(Register);
and this is one of my actions auth.js where i request my api
import axios from "axios";
import { setAlert } from './alert'
import {
REGISTER_SUCCESS,
REGISTER_FAIL
} from './types'
//Register user
export const register = ( { name, email, password } ) => async dispatch => {
const config = {
headers: {
'Content-type': 'application/json'
}
}
const body = JSON.stringify({ name , email, password });
try {
const res = await axios.post('http://localhost:5000/api/users', body, config);
dispatch({
type: REGISTER_SUCCESS,
payload: res.data
});
} catch (error) {
const errors = error.response.data.errors;
if(errors){
errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
}
dispatch({
type:REGISTER_FAIL
});
}
}
I am pretty sure this might be an axios error on how i am trying to perform a request or a redux mistake.
My app works fine, if i don´t enter or enter invalid data to my registration form all my validation alerts show up. The issue is when i submit the form and try to send the data to register the new user.
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);