I'm a beginner at react. I'm getting the following error when I am trying to register a user using passport-local authentication. I'm not too much familiar with the passport with jsx components but used to with ejs. I am getting confused about routes "/". I have researched all the questions posts but no solution works for me :( Am I doing wrong in routes "/register" or "/login"???
- My end goal is to authenticate users by using passport-local.
Please HELP ME!!
File structure looks like this: File structure
Here server.js :
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const path = require('path');
const mongoose = require("mongoose");
const passport = require("passport");
const cookieParser = require("cookie-parser");
const bcrypt = require("bcryptjs");
const expressSession = require("express-session");
const port = process.env.PORT || 5000;
const app = express();
app.use(cors());
app.use(cors({
credentials: true, origin: 'http://localhost:3000'
}));
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(path.join(__dirname, 'public')));
app.set('src', path.join(__dirname, '/src'));
app.set('view engine', 'jsx');
app.engine('jsx', require('express-react-views').createEngine());
app.use(expressSession({
secret: "This is my little secret.",
resave: false,
saveUninitialized: true
}));
app.use(cookieParser("This is my little secret."));
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect(process.env.MONGODB_URI)
.then(() => app.listen(port, () => console.log("Server is running on port 5000")))
.catch((err) => console.log(err.message));
const connection = mongoose.connection;
connection.once("open", () => {
console.log("MongoDB database connection established successfully");
});
// Using the flash middleware provided by connect-flash to store messages in session
// and displaying in templates
const flash = require('connect-flash');
app.use(flash());
// Initialize Passport
const initPassport = require('../functions/passport/init');
initPassport(passport);
const usersRouter = require("./routes/users")(passport);
app.use("/", usersRouter);
module.exports = app;
users.js:
const app = express.Router();
var isAuthenticated = function (req, res, next) {
// if user is authenticated in the session, call the next() to call the next request handler
// Passport adds this method to request object. A middleware is allowed to add properties to
// request and response objects
if (req.isAuthenticated())
return next();
// if the user is not authenticated then redirect him to the login page
res.redirect('/');
}
module.exports = function(passport){
/* GET login page. */
app.get('/', function(req, res) {
// Display the Login page with any flash message, if any
res.render('login', { message: req.flash('message') });
});
/* Handle Login POST */
app.post('/login', passport.authenticate('login', {
successRedirect: '/secrets',
failureRedirect: '/',
failureFlash : true
}));
/* GET Registration Page */
app.get('/register', function(req, res){
res.render('register',{message: req.flash('message')});
});
/* Handle Registration POST */
app.post('/register', passport.authenticate('register', {
successRedirect: '/home',
failureRedirect: '/register',
failureFlash : true
}));
/* GET Home Page */
app.get('/home', isAuthenticated, function(req, res){
res.render('home', { user: req.user });
});
/* Handle Logout */
app.get('/logout', function(req, res, next) {
req.logout(function(err) {
if (err) { return next(err); }
res.redirect('/')
})
});
return app;
}
register.jsx:
import axios from "axios";
import qs from "qs";
function Register(){
const [user, setUser] = useState({
email: "",
password: ""
});
function handleChange(event) {
const { name, value } = event.target;
setUser((prevValue) => {
return {
...prevValue,
[name]: value
};
});
}
function submitUser(event){
console.log(user);
const data = qs.stringify({
email: user.email,
password: user.password
});
const headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
};
axios({
method: "POST",
data: data,
headers: headers,
withCredentials: true,
url: "http://localhost:5000/register",
}).then((res) => console.log(res));
setUser({
email: "",
password: ""
});
event.preventDefault();
};
return (
<div className="container mt-5 home">
<h1>Register</h1>
<div className="row">
<div className="col-sm-8">
<div className="card">
<div className="card-body">
<form >
{/* don't use "action=''" & "method: POST" while using axios routing
cause it's doing same thing.
*/}
<div className="form-group">
<label htmlFor="email">Email</label>
<input
type="email"
className="form-control"
name="email"
placeholder="Enter your email"
onChange={handleChange}
value={user.email}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
type="password"
className="form-control"
name="password"
placeholder="Enter your password"
onChange={handleChange}
value={user.password}
/>
</div>
<button type="submit"
className="btn btn-dark" onClick={submitUser}>Register</button>
</form>
</div>
</div>
</div>
</div>
</div>
)
}
export default Register;
package.json:
"name": "secrets-app",
"version": "0.1.0",
"private": true,
"proxy": "http://localhost:5000/",
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.3.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"
]
}
}
login.jsx:
import axios from "axios";
import qs from "qs";
function Login(){
const [user, setUser] = useState({
email: "",
password: ""
});
function handleChange(event) {
const { name, value } = event.target;
setUser({...user, [name]: value});
console.log(event.target.name);
console.log(event.target.value);
};
function handleSubmit(event){
const data = qs.stringify({
email: user.email,
password: user.password
});
const headers = {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
}
axios.post("http://localhost:5000/users/login", {withCredentials: true}, data, headers)
.then(res => console.log(res.data))
.catch(err => console.log(err))
setUser({
email: "",
password: ""
});
event.preventDefault();
};
return (
<div className="container mt-5 home">
<h1>Login</h1>
<div className="row">
<div className="col-sm-8">
<div className="card">
<div className="card-body">
<form>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
type="text"
placeholder="Enter your email"
className="form-control"
name="email"
required
onChange={handleChange}
value={user.email}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
type="password"
className="form-control"
placeholder="Enter your password"
name="password"
required
onChange={handleChange}
value={user.password}
/>
</div>
<button type="submit" onClick={handleSubmit}
className="btn btn-dark">Login</button>
</form>
</div>
</div>
</div>
</div>
</div>
);
};
export default Login;
App.jsx:
import {Routes, Route} from 'react-router-dom';
import Login from "./login";
import Home from './home';
import Register from "./register";
import Submit from "./submit";
import Secrets from "./secrets";
import axios from "axios";
function App(){
const [users, setUsers] = useState([]);
useEffect(() => {
axios.get("http://localhost:5000/")
.then(res => {
setUsers(res.data);
})
.catch(err => {
console.log(err);
});
});
function addUser(newUser) {
setUsers(prevUsers => {
return [...prevUsers, newUser];
});
}
return (
<div className="app">
<Routes>
<Route path="/" element={<Home />} />
<Route exact path="login" element={<Login />} />
<Route exact path="register" element={users.map((user) =>
{
return(
<Register
key={user._id}
_id={user._id}
email={user.email}
password={user.password}
onAdd={addUser} /> )}
)
} />
<Route exact path="submit" element={<Submit />} />
<Route exact path="secrets" element={<Secrets />} />
</Routes>
</div>
);
};
export default App;
src/components/index.js:
import ReactDOM from 'react-dom';
import { BrowserRouter, Routes, Route} from 'react-router-dom';
import App from "./components/App";
import Login from "./components/login";
import Register from "./components/register";
import Submit from "./components/submit";
import Secrets from "./components/secrets";
ReactDOM.render(
<React.StrictMode>
<BrowserRouter>
<Routes>
<Route index path="/*" element={ <App /> }/>
<Route exact path="/login" element={ <Login /> }/>
<Route exact path="/register" element={ <Register /> } />
<Route exact path="/submit" element={ <Submit /> } />
<Route exact path="/secrets" element={ <Secrets /> } />
</Routes>
</BrowserRouter>
</React.StrictMode>, document.getElementById("root"));
user.model.js:
const Schema = mongoose.Schema;
const userSchema = new Schema({
id: String,
email:
{
type: String,
required: true,
unique: true
},
password:
{
type: String,
required: true
}
});
module.exports = mongoose.model("User", userSchema);
I am facing this issue for a few days and trying to solve till overnight. ANYONE PLS HELP!!