I'm creating REST APIs using NodeJS and MongoDB as a database.
I'm using passport for handling the authentication.
I'm wondering why the sessions are not persistent! Also why the deserialization is never invoked!
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
console.log(user, "deserialization"); // --> Never invoked!
done(err, user);
});
});
passport.use(User.createStrategy());
app.use(
session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }) // --> Sessions has been saved to database after each login or register
})
);
app.use(passport.initialize());
app.use(passport.session());
exports.getRestaurants = async (req, res) => {
console.log(req.session); // --> Not contains any user info
console.log(req.user); // -->undefined and this is my problem
const restaurants = await liveRestaurants.find().sort({ rate: -1 });
if (!restaurants) return next();
res.status(200).json({ restaurants });
};
After my research, I concluded that it might be for the following reasons:
app.use should be in the correct order
localhost port have an effect on it "as I read"
cluster
and other
Related
I am setting up my NodeJS & Express App, using Passport for authentication with Google Sign In and Login. Everything works very well when working on localhost.
The signin process works very well, and I can see the user information attached to req.user contains all user information.
However, right after that, when calling any route, req.user is undefined
I try desperately, to check if any session doesent exist to redirected that, on my login page, but it gives me some error based on Unexpected token
index.js:
const express = require("express");
const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const app = express()
const port = 5000
// if user is not logged-in redirect back to login page
app.use(function(req, res, next) {
if (req.session.user == null){
res.redirect('http://localhost:3000/login');
} else {
next();
}
});
app.use(
session({
secret: 'keyboard cat',
resave: false,
cookie: { httpOnly: false, secure: false, maxAge: 60 * 1000},
saveUninitialized: false,
})
)
passport.use(
new GoogleStrategy({
clientID: "process.env.clientID",
clientSecret: "process.env.clientSecret",
callbackURL: '/auth/google/callback',
},
async (accessToken, refreshToken, profile, done) => {
const existingUser = await User.findOne({
providerId: profile.id,
})
if (existingUser) {
return done(null, existingUser);
}
const user = await new User({
provider: profile.provider,
providerId: profile.id,
displayName: profile.displayName,
}).save()
done(null, user);
})
)
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (obj, done) {
done(null, done);
});
My error :
ERROR Error in fetch(): request to http://localhost:3000/login failed, reason: read ECONNRESET
at ClientRequest.<anonymous> (node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (events.js:400:28)
at Socket.socketErrorListener (_http_client.js:475:9)
at Socket.emit (events.js:400:28)
at emitErrorNT (internal/streams/destroy.js:106:8)
at emitErrorCloseNT (internal/streams/destroy.js:74:3)
at processTicksAndRejections (internal/process/task_queues.js:82:21)
Thank you
For starters, move this:
// if user is not logged-in redirect back to login page
app.use(function(req, res, next) {
if (req.session.user == null){
res.redirect('http://localhost:3000/login');
} else {
next();
}
});
to be after this:
app.use(
session({
secret: 'keyboard cat',
resave: false,
cookie: { httpOnly: false, secure: false, maxAge: 60 * 1000},
saveUninitialized: false,
})
)
There will NEVER be a req.session until AFTER the session middleware runs so any code that tries to use req.session must be after the session middleware.
Also change this:
if (req.session.user == null)
to:
if (!req.session || !req.session.user)
So the code is safe if req.session doesn't exist.
I have been working on a web-app similar to this https://rustbet.com. Here's some code :
passport.serializeUser(function(user, done) {
done(null, JSON.stringify(user));
});
passport.deserializeUser(function(obj, done) {
done(null, JSON.parse(obj));
});
I'm serializing the users locally.
passport.use(new SteamStrategy({
returnURL: 'http://localhost:80/auth/steam/return',
realm: 'http://localhost:80/',
apiKey: '------------------'
},
function(identifier, profile, done) {
process.nextTick(function () {
profile.identifier = identifier;
return done(null, profile);
});
}
));
Using steam passport strategy
app.use(session({
secret: '---------',
name: 'user_session',
resave: true,
saveUninitialized: true}));
Sessions
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
And here's how i'm currently using the data
How can I use the req.user object outside of a http request/ EJS template? For instance in a socket.io app that i need. I have surfed stackoverflow and found a multitude of answers but none of them were recent. Also, I'm open to any best practices that i most likely missed.
Look, i've made a mean stack app with register/login using passportjs, and it was fine, when i change to angular2(the other was on angularjs) i've made the backend side and i think it works but i dont know how to test it on the fronted side, i know it has to be something with the url in the <a href=""> but when i put the route that passport gives me, example: /auth/facebook, my aplication does nothing... well it does something, send me to the homepage :c
here is my code so far on the backend side
const FacebookStrategy = require('passport-facebook').Strategy;
const session = require('express-session');
const secret = require('../config/database')
const user = require('../models/user')
module.exports = function(app, passport){
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
passport.serializeUser(function(user, done) {
token = jwt.sign({email: user.email}, secret, {expiresIn : '24h'});
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: '350645212059140',
clientSecret: '8a990aec6db37cc3535f4223c235c427',
callbackURL: "http://localhost:4200/auth/facebook/callback",
profileFields: ['id','displayName','email']
},
function(accessToken, refreshToken, profile, done) {
console.log(profile);
// User.findOrCreate(..., function(err, user) {
// if (err) { return done(err); }
// done(null, user);
// });
done(null, profile)
}
));
app.get('/auth/facebook',passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback' , passport.authenticate('facebook', {failureRedirect: '/login'}), function(res, res){
if (err) {
console.log(err)
}else{
res.send('wi')
}
})
return passport;
}
my question is, how can i implement this on the fronted side, remember angular 4 :)
Here is pseudo code for this.
Step 1: When you are submitting your form using ngSubmit call a function for instance passportLogin().
Step 2: Now in your component use this function and do an HTTP post request to your node js(express js) URL, for example, auth/login.
Step 3: In the server side write a routing
var express = require('express'),
router = express.Router();
module.exports = function(passport){
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
}
I have created a simple user login application following an online tutorial using Node, Express and Passport. Login works correctly but I would like to get the username of the current logged in user and I can't seem to get this working.
I have the following in my app.js:
/// Configuring Passport
var passport = require('passport');
var expressSession = require('express-session');
app.use(expressSession({
secret: 'cookie_secret',
name: 'cookie_name',
proxy: true,
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session({
secret: 'cookie_secret',
name: 'cookie_name',
proxy: true,
resave: true,
saveUninitialized: true
}));
From what I read in similar posts, I need to expose the username so that I may use it in other files. I tried to do this in my app.js:
app.get('/home', function(req, res) {
res.render('home.jade', { username: req.user.username });
});
Home is a route where I would like to use the the username, and I am trying to access the username with an alert like the following:
alert(req.user.username);
This does not work, the req object is undefined...I'm not sure what I am missing?
Managed to get this working. In my app.js I have:
app.get('/home', function(req, res) {
res.render('home.jade', { username: req.user.username });
});
And then in my /home route I can access the username by doing:
req.user.username
You are mixing two things, one is the client side, and the other is the server side, both use javascript but for render server side code in the cliente side you could not use directly in the client side. you must pass to the view as you do with
app.get('/home', function(req, res) {
res.render('home.jade', { username: req.user.username });
});
here you expose the username variable to the view
In the jade file you should do this
alert(#{username})
instead of
alert(req.user.username)
try:
app.use(cookieParser());
app.use(session({
secret: 'cookie_secret',
name: 'cookie_name',
proxy: true,
resave: true,
saveUninitialized: true
})
);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
on controller use req.user
{ username: user.local.username }
Please go with the below link
https://github.com/hnagarkoti/passportauthenticationWorking
I'm using Cloud 9 to setup a basic social media website and I am having trouble with registration and authentication of users. I'm using Node.js, express and passport for authentication, and mongoDB as a database.
// PASSPORT Setup //
app.use(require("express-session")({
secret: "I am the best",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// INDEX Page
app.get("/", function(req, res) {
res.render("landing-page");
});
// REGISTER NEW
app.get("/register", function(req, res) {
res.render("user/register");
});
// REGISTER CREATE
app.post("/register", function(req, res) {
var user = req.body.user;
var newUser = new User({
username: user.email,
firstName: user.firstName,
lastName: user.lastName,
});
User.register(newUser, user.password, function(err, user) {
if(err) {
console.log(err);
return res.render("user/register");
}
passport.authenticate("local")(req, res, function() {
res.redirect("/");
});
});
});
// Login routes
app.get("/login", function(req, res) {
res.render("login");
});
app.post("/login", passport.authenticate("local", {
successRedirect: "/",
failureRedirect: "/login"
}) , function(req, res) {
});
// Logout route
app.get("/logout", function(req, res) {
req.logout();
res.redirect("/");
});
However whenever I run this, when I sign up a new user, it gives me a webpage with just "Bad Request", however the user is created in the database.
Look at this answer; the bad request is not a problem with your passport method: that indicates the request you try to make is not correct:
Did you set the head at: Content-Type: application-json?
Also update the bodyParser to the last version. This solved a similar problem I had.