I have a registration page that is supposed to post user input from a form:
// Registration.jsximport 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.jsconst express = require('express');const connectDB = require('./config/db.js');var cors = require('cors');const proxyMiddleware = require('./middleware/Proxy.js');const app = express();// Connect to MongoDBconnectDB();// Middlewareapp.use(express.json()); // Parse JSON bodiesproxyMiddleware(app);// Define CORS optionsconst corsOptions = { origin: 'http://localhost:3000', credentials: true, // Access-Control-Allow-Credentials header optionSuccessStatus: 200};app.use(cors(corsOptions));// Routesapp.use('/api/auth', require('./routes/auth'));// Define portconst PORT = process.env.PORT || 5000;app.get('/', (req, res) => { res.send('Hello, welcome to the API server!');});// Start serverapp.listen(PORT, () => { console.log(`Server is running on port ${PORT}`);});module.exports=app;
Proxy response header:
HTTP/1.1 204 No Contentx-powered-by: Expressaccess-control-allow-origin: http://localhost:3000vary: Origin, Access-Control-Request-Headersaccess-control-allow-credentials: trueaccess-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETEaccess-control-allow-headers: content-typecontent-length: 0date: Wed, 17 Apr 2024 14:20:11 GMTconnection: 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.jsconst 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 Routerouter.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 Routerouter.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 Routerouter.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 routerouter.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 routerouter.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" ] }}