Reputation: 95
I am trying to use passport authentication with a local strategy provided by passport-local-mongoose to authenticate a user. If the user is authenticated, then he is allowed to view the /secret route, else he gets a bad request message (provided by passport).
The weird part is that the authentication works for the login POST route, which successfully redirects to the /secret page upon correct credentials. But on redirection, the user gets a bad request which means that authentication fails at the /secret route. This is very confusing as the user could only be redirected to /secret if he was successfully authenticated upon login, but upon redirection to /secret, authentication fails and a bad request error is sent.
User Schema:
const mongoose = require("mongoose"),
passportLocalMongoose = require("passport-local-mongoose");
const userSchema = new mongoose.Schema({
username: String,
password: String
});
userSchema.plugin(passportLocalMongoose);
module.exports = new mongoose.model("User", userSchema);
Server Configuration:
const express = require("express"),
mongoose = require("mongoose"),
passport = require("passport"),
bodyParser = require("body-parser"),
LocalStrategy = require("passport-local"),
expressSession = require("express-session");
const User = require("./models/user");
const app = express();
app.set("view engine", "ejs");
app.use(
expressSession({
secret: "Lorem Ipsum",
resave: false,
saveUninitialized: false
})
);
app.use(bodyParser.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect("mongodb://localhost:27017/auth-test", {
useNewUrlParser: true,
useUnifiedTopology: true
});
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Login and Secret Routes:
app.post(
"/login",
passport.authenticate("local", {
successRedirect: "/secret",
failureRedirect: "/register"
})
);
app.get("/secret", passport.authenticate("local"), (req, res) => {
res.render("secret");
});
Login form in case it is needed, used on the /login GET route:
<form action="/login" method="POST">
<input type="text" placeholder="Username" name="username" autocomplete="off" />
<input type="password" placeholder="Password" name="password" autocomplete="off" />
<button type="submit">Submit</button>
</form>
Upvotes: 0
Views: 247
Reputation: 736
Checking passport-local code, it seems that Authenticate()
is used to verify the user's credentials (username, password), so basically you'll only need to use it in /login route.
To verify if the user is authorized to access a protected route, you can use req.isAuthenticated()
instead.
app.get("/secret", (req, res) => {
if (!req.isAuthenticated()) {
return res.sendStatus(401);
}
res.render("secret");
});
Upvotes: 1