I have a registration page that is supposed to post user input from a form:
// Registration.jsx
import React, { useState } from 'react';
import axios from 'axios';
const Registration = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [successMessage, setSuccessMessage] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
// Validation logic (you can use a library like Yup for form validation)
if (!email || !password) {
setError('Email and password are required.');
return;
}
console.log("Test");
// Registration API call
const response = await axios.post('http://localhost:5000/api/auth/register', { email, password });
console.log(response);
setSuccessMessage(response.data.message);
} catch (error) {
setError(error.response.data.message);
}
}
return (
<div className="container">
<div className="row">
<div className="col-md-6 offset-md-3">
<h2>Registration</h2>
{error && <div className="alert alert-danger">{error}</div>}
{successMessage && <div className="alert alert-success">{successMessage}</div>}
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label htmlFor="email" className="form-label">Email address</label>
<input type="email" className="form-control" id="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
</div>
<div className="mb-3">
<label htmlFor="password" className="form-label">Password</label>
<input type="password" className="form-control" id="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
</div>
<button type="submit" className="btn btn-primary">Register</button>
</form>
</div>
</div>
</div>
);
}
export default Registration;
When I submit the form nothing happens, I go to the network tab to see whats going on and after a while of pending the request header eventually says 408 Request time out. Thats when these 3 show up in the console:
Access to XMLHttpRequest at 'http://localhost:5000/api/auth/register' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
POST http://localhost:5000/api/auth/register net::ERR_FAILED 408 (Request Timeout)
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'data')
at handleSubmit (main.18ffb0dca439882a5d90.hot-update.js:50:31)
I’m not too sure its the first error because I set up proxy middleware for the cross origin access and the proxy request headers seem to be completing just fine every time:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true, // Needed for virtual hosted sites
ws: true, // Proxy websockets
pathRewrite: {
'^/api': '' // remove base path
}
})
);
};
// server.js
const express = require('express');
const connectDB = require('./config/db.js');
var cors = require('cors');
const proxyMiddleware = require('./middleware/Proxy.js');
const app = express();
// Connect to MongoDB
connectDB();
// Middleware
app.use(express.json()); // Parse JSON bodies
proxyMiddleware(app);
// Define CORS options
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true, // Access-Control-Allow-Credentials header
optionSuccessStatus: 200
};
app.use(cors(corsOptions));
// Routes
app.use('/api/auth', require('./routes/auth'));
// Define port
const PORT = process.env.PORT || 5000;
app.get('/', (req, res) => {
res.send('Hello, welcome to the API server!');
});
// Start server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
module.exports=app;
Proxy response header:
HTTP/1.1 204 No Content
x-powered-by: Express
access-control-allow-origin: http://localhost:3000
vary: Origin, Access-Control-Request-Headers
access-control-allow-credentials: true
access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
access-control-allow-headers: content-type
content-length: 0
date: Wed, 17 Apr 2024 14:20:11 GMT
connection: close
I belive the problem lies in the last error, in an attempt to fix it I consol.log() the problem areas as shown by the registration.jsx page. The console log for test runs fine but the console log after this statement doesnt even run
const response = await axios.post('http://localhost:5000/api/auth/register', { email, password });
Is there something wrong with the statement? I’ll include anything I think you might need bellow, thanks in advance.
//auth.js
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const User = require('../models/user.js');
const registerValidation = require('../middleware/validation.js');
const { validationResult } = require('express-validator');
//Register Route
router.post('/register', registerValidation, async (req, res) => {
// Validate request body
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
try {
// Check if user already exists
let user = await User.findOne({ email });
if (user) {
return res.status(400).json({ msg: 'User already exists' });
}
// Create new user
user = new User({
email,
password
});
// Hash password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(password, salt);
// Save user to database
await user.save();
// Generate JWT token
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
process.env.JWT_SECRET,
{ expiresIn: '1d' },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
//Email Verification Route
router.get('/verify/:token', async (req, res) => {
const token = req.params.token;
try {
// Verify token
const decoded = jwt.verify(token, process.env.JWT_SECRET);
// Update user's verified status
await User.findByIdAndUpdate(decoded.user.id, { verified: true });
res.json({ msg: 'Email verified successfully' });
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
// Login Route
router.post('/login', async (req, res) => {
const { email, password } = req.body;
try {
// Check if user exists
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ msg: 'Invalid Credentials' });
}
// Check if password matches
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
return res.status(400).json({ msg: 'Invalid Credentials' });
}
// Check if user is verified
if (!user.verified) {
return res.status(400).json({ msg: 'Please verify your email' });
}
// Generate JWT token
const payload = {
user: {
id: user.id
}
};
jwt.sign(
payload,
process.env.JWT_SECRET,
{ expiresIn: '1d' },
(err, token) => {
if (err) throw err;
res.json({ token });
}
);
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
// Forgot password route
router.post('/forgot-password', async (req, res) => {
const { email } = req.body;
try {
// Check if user exists
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ msg: 'User not found' });
}
// Generate verification code
const verificationCode = Math.floor(100000 + Math.random() * 900000);
// Implement logic to send verification code to user's email using SendGrid
res.json({ msg: 'Verification code sent to your email' });
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
// Verify Code route
router.post('/verify-code', async (req, res) => {
const { email, verificationCode } = req.body;
try {
// Check if user exists
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ msg: 'User not found' });
}
// Check if verification code matches
if (user.verificationCode !== verificationCode) {
return res.status(400).json({ msg: 'Invalid verification code' });
}
// If verification code matches, update user's verified status
user.verified = true;
// Clear verification code after successful verification
user.verificationCode = null;
await user.save();
res.json({ msg: 'Verification code verified' });
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
//Rest Password route
router.post('/reset-password', async (req, res) => {
const { email, newPassword } = req.body;
try {
// Check if user exists
const user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ msg: 'User not found' });
}
// Hash new password
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(newPassword, salt);
// Save new password to database
await user.save();
res.json({ msg: 'Password reset successful' });
} catch (err) {
console.error(err.message);
res.status(500).send('Server Error');
}
});
module.exports = router;
{
"name": "backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "Percy",
"license": "ISC",
"dependencies": {
"@sendgrid/mail": "^8.1.3",
"axios": "^1.6.8",
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"express-validator": "^7.0.1",
"http-proxy-middleware": "^3.0.0",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.3.1",
"nodemailer": "^6.9.13",
"nodemon": "^3.1.0",
"sendgrid": "^5.2.3"
}
}
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.8",
"bootstrap": "^5.3.3",
"react": "^18.2.0",
"react-bootstrap": "^2.10.2",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}