I recently learnt authentication with node and passport js, but the truth is I only understand it when it's the email and password. But what if you're trying to register a user with multiple input, it feels as if there's no way you can do that. I've tried several times but it's not working. I have a username, email and password field which I want to store in the database with passport js but I've been getting several errors:
I tried this at first:
html:
<form action="/register" method="post">
<div class="name-input form">
<input type="text" name="username" id="name" required /><br />
<label for="username">Name</label>
<div class="error-message" id="name-error"></div>
</div>
<div class="email-input form">
<input type="email" id="email" name="email" required /><br />
<label for="">Email</label>
<div class="error-message" id="name-error"></div>
</div>
<div class="password-input form">
<input type="password" id="password" name="password" required /><br />
<label for="">Password</label>
<div class="error-message" id="name-error"></div>
</div>
<div class="cta">
<button type="submit">Create account</button>
<div class="social-media-btn">
<img src="Assest/Google-logo-large.png" alt="google log" /> Sign up with
Google
</div>
<span>Already have an account? <a href="/login">Log in</a></span>
</div>
</form>
sever code below:
require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
const ejs = require("ejs")
const bodyParser = require("body-parser")
const session = require("express-session")
const passport = require("passport");
const localStrategy = require('passport-local').Strategy;
const app = express();
app.use(express.static("public"));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: false }));
// Configure express-session middleware
app.use(
session({
secret: "secret-key",
resave: false,
saveUninitialized: false
})
);
// Initialize Passport.js middleware
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true })
.then(() => console.log("DB connection successfull"))
.catch(err => console.log(err));
const User = require("./config/database");
// Configure Passport.js to use LocalStrategy
passport.use(
new localStrategy({ usernameField: "email" }, User.authenticate())
);
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.get("/register", (req, res) => {
res.render("register")
})
// Register route to handle registration
app.post("/register", (req, res) => {
const { username, email, password } = req.body;
// Create a new user with username, email, and password
const newUser = new User({ username, email });
User.register(newUser, password, (err, user) => {
if (err) {
console.log(err);
res.redirect("/register");
} else {
passport.authenticate("local")(req, res, () => {
console.log("Registration successful");
res.redirect("/homepage");
});
}
});
});
// Login route to handle login
app.post("/login", passport.authenticate("local"), (req, res) => {
console.log("Login successful");
res.redirect("/homepage");
});
// Homepage route to handle authenticated user access
app.get("/homepage", (req, res) => {
// Check if user is authenticated
if (req.isAuthenticated()) {
res.send("Welcome to the homepage!");
} else {
res.redirect("/login");
}
});
// Logout route to handle user logout
app.get("/logout", (req, res) => {
req.logout();
res.redirect("/login");
});
// Start the server
app.listen(3000, () => {
console.log("Server started on http://localhost:3000");
});
this is the code for the database:
require("dotenv").config;
const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose")
const customDesignSchema = new mongoose.Schema({
name: String,
email: String,
password: String
});
// Set up Passport-Local-Mongoose plugin
customDesignSchema.plugin(passportLocalMongoose, {
usernameField: "email"
});
const User = new mongoose.model("User", customDesignSchema);
module.exports = User;
This code works but It only saves the email and the hashed password to the database. It doesn't save the username.
############## Second example ###########
require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
const ejs = require("ejs")
const bodyParser = require("body-parser")
const session = require("express-session")
const passport = require("passport");
const localStrategy = require('passport-local').Strategy;
const MongoStore = require('connect-mongo');
const app = express();
app.use(express.static("public"));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: false }));
// Configure express-session middleware
app.use(
session({
secret: "secret-key", // Replace with your own secret key
resave: false,
saveUninitialized: false
})
);
// Initialize Passport.js middleware
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true })
.then(() => console.log("DB connection successfull"))
.catch(err => console.log(err));
const User = require("./config/database");
// Configure Passport.js to use LocalStrategy
passport.use(
new localStrategy({
usernameField: "email", // Use "email" field as the username
passwordField: "password" // Use "password" field as the password
}, User.authenticate())
);
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.get("/register", (req, res) => {
res.render("register")
})
// Register route to handle registration
app.post("/register", (req, res) => {
const { username, email, password } = req.body;
// Create a new user with username, email, and password
const newUser = new User({ username, email });
User.register(newUser, password, (err, user) => {
if (err) {
console.log(err);
res.redirect("/register");
} else {
passport.authenticate("local")(req, res, () => {
console.log("Registration successful");
res.redirect("/homepage");
});
}
});
});
// Login route to handle login
app.post("/login", passport.authenticate("local"), (req, res) => {
console.log("Login successful");
res.redirect("/homepage");
});
// Homepage route to handle authenticated user access
app.get("/homepage", (req, res) => {
// Check if user is authenticated
if (req.isAuthenticated()) {
res.send("Welcome to the homepage!");
} else {
res.redirect("/login");
}
});
// Logout route to handle user logout
app.get("/logout", (req, res) => {
req.logout();
res.redirect("/login");
});
db
require("dotenv").config;
const mongoose = require("mongoose");
const passportLocalMongoose = require("passport-local-mongoose")
const customDesignSchema = new mongoose.Schema({
name: String,
email: String,
password: String
});
// Set up Passport-Local-Mongoose plugin
customDesignSchema.plugin(passportLocalMongoose);
const User = new mongoose.model("User", customDesignSchema);
module.exports = User;
this works, it saves the username, email and password in the db but it redirects me to a blank black page with the text unauthorized.
I've seen multiple videos and read multiple articles but they all use only username and password. And also they do it differently, it feels as if there is not a single way of doing it. Some hash their password others don't. Some also implement some things in local strategy which I don't even understand. It's been two days now, and it still feels as if I'm not making any progress.