Reputation: 249
So I want let's say p.x on /profile I want to know if the user is logged in with a command!
So when he goes to home page "/" it's going to render either the profile.ejs if he is logged in or the home.ejs to register and log in.But I don't when do that with app.get('/login'... because I need it again when I am already using the profile to redirect to another page but he has to be logged in to go there.
Here is code:
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}
const express = require('express')
const app = express()
const bcrypt = require('bcrypt')
const passport = require('passport')
const flash = require('express-flash')
const session = require('express-session')
const methodOverride = require('method-override')
const initializePassport = require('./passport-config')
var mongodb = require('mongodb');
const bodyParser = require('body-parser');
initializePassport(
passport,
email => users.find(user => user.email === email),
id => users.find(user => user.id === id)
)
var urlencodedParser = bodyParser.urlencoded({extended:false})
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
const users = []
var http = require('http');
/* ************ */
app.use(express.static(__dirname + '/public'));
app.set('view-engine', 'ejs')
app.use(express.urlencoded({ extended: false }))
app.use(flash())
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}))
app.use(passport.initialize())
app.use(passport.session())
app.use(methodOverride('_method'))
app.use( bodyParser.json() );
var dbConn = mongodb.MongoClient.connect('mongodb://localhost:27017/');
var path = require('path');
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/nyg', {useNewUrlParser: true});
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: String,
password: String
});
const User = mongoose.model('users', userSchema);
app.post('/register', async (req, res, next) => {
const user = await User.findOne({
email: req.body.email,
password: req.body.password
}).exec();
if (user) {
res.redirect('/register');
next();
}
else new User({
email: req.body.email,
password: req.body.password
})
.save()
.exec();
res.redirect('/login');
next();
});
app.post('/login', async (req, res, next) => {
const user = await User.findOne({
email: req.body.email,
password: req.body.password
});
if (user) res.redirect('/');
else res.redirect('/login');
next();
});
app.get('/', (req, res) => {
if (req.isAuthenticated()) res.render('profile.ejs')
else res.render('index.ejs')
})
app.get('/login', (req, res) => {
res.render('login.ejs')
})
app.get('/register', (req, res) => {
res.render('register.ejs')
})
app.delete('/logout', (req, res) => {
req.logOut()
res.redirect('/login')
})
app.listen(process.env.PORT || 3000, process.env.IP || '0.0.0.0' );
Upvotes: 1
Views: 19225
Reputation: 1
You could do something like this:
app.use(function(req, res, next){
if ((req.session.userid == "") || (typeof req.session.userid === 'undefined') || (req.session.userid === null)) {
res.redirect(/* path for login here */)
} else next() // or do something else if there logged in
})
So you would end up with something alike tis:
const express = require('express');
const cookieParser = require("cookie-parser");
const sessions = require('express-session');
const app = express();
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser());
const oneDay = 1000 * 60 * 60 * 24; // time in milliseconds
//session middleware
app.use(sessions({
secret: /* your secret here */,
saveUninitialized:true,
cookie: { maxAge: oneDay },
resave: false
}));
// All login routes here
app.use(function(req, res, next){
if ((req.session.userid == "") || (typeof req.session.userid === 'undefined') || (req.session.userid === null)) {
res.redirect(/* path for login here */)
} else next() // or do something else if there logged in
})
//all other routes here
it is VERY important that all login routes are BEFORE the check function, otherise it will create an infinite loop! Also, inside the login routes, make sure the following code is added inside the logging in route so that the req.session.userid
has a value:
req.session.userid = // value or other variable here
Feel free to send me any notes, comments, questions & more!
Upvotes: 0
Reputation: 18
well first write how you want to define it..
Route-login => token found => verify and login and redirect to dashboard.
Route-login => token not found => next()
create a middleware name it anything u want.. (i named it as loginBefore)
const User = require("../model/User");
const jwt = require("jsonwebtoken");
exports.loginBefore = async (req, res, next) => {
const tokenFind = () => {
try {
// check if token found in cookies
if (req.cookies.token) {
return req.cookies.token;
}
// check if token found body
if (req.body.token) {
return req.body.token;
}
//check if token found in header
if (req.header("Authorization")) {
return req.header("Authorization").replace("Bearer ", "");
}
} catch (error) {
console.log(error);
}
};
const token = tokenFind();
if (token) {
// decoding the token with scerect key
const decoded = jwt.verify(token, process.env.JWTSECRETWORD);
// asign to a var
const found = await User.findById(decoded.id);
if (found) {
return res.status(200).redirect("/dashboard");
} else {
return res.status(400).redirect("/login");
}
}
next();
};
later go to ur router page
const { loginBefore } = require("../middleware/loginBefore");
make it require
router.route("/login").post(loginBefore, login);
then add this below after requiring it. (loginBefore is middleware that checks for token)
const userRouter = require("./route/user");
app.use("/", userRouter);
then add this in app.js
HOPE THIS HELPS...
i'm checking if token is found in cookies, body or in header then if it was found verify the token and find the user from mongodb using mongoose and redirect user to dashboard.
if token was not found or token contains modified data then redirect to login page.
Upvotes: 0
Reputation: 548
Passport already contains everything you need to log in a user and check if a user is authenticated in any route.
You have correctly identified that the req.isAuthenticated()
function is provided by the middleware to see if a user is currently authenticated.
The user must be logged in with Passport for the function to work. In your app.post('/login'
route, make sure that you are authenticating the user against Passport like this:
passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login' }));
The Passport documentation clearly explains how to set it up for username and password authentication if your current configuration isn't working. The examples they give already use mongoose to retrieve users from the database.
req.isAuthenticated()
can then be used in combination with an if statement from any route to conditionally execute code depending on if the user is logged in.
if (req.isAuthenticated()) {
// The user is logged in
} else {
// The user is logged out
}
Alternatively, you can create a simple middleware that will only allow access to a route if the user is logged in.
function loggedIn(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect('/login');
}
}
Use it like this:
app.get('/protectedRoute', loggedIn, (req, res) => {
// The user is logged in otherwise they would have been redirected
})
See my GitHub repo for a fully working express & passport login example. Just follow the instructions in the readme to run it.
Upvotes: 8