CURRENT SCENARIO
Once I log in via social auth it shows the username and provider detail on the page. but if I refresh again it shows the error. I am sending the user object via render but still, it doesn't fetch the details. I don't understand why.
{"error":{"message":"Failed to fetch user profile"}}
Below is my express session snippet in my app.js file
app.use(expressSession({
name: 'Session',
maxAge: 24 * 60 * 60 * 1000,
secret: [keys.session.cookieKey],
resave: true,
saveUninitialized: true
}))
app.use(passport.initialize())
app.use(passport.session())
Below is my oauth.js file
const express = require('express');
const router = express.Router();
const passport = require('passport')
router.get('/login',(req, res, next) => {
//create a func where we check if the user logged in then show the profile page , if not logged in then show login page
res.render('login')
});
router.get('/logout', (req, res, next) => {
req.session = null
req.logout()
res.redirect('/')
});
router.get('/google', passport.authenticate('google', {
scope: ['profile']
}));
router.get('/facebook', passport.authenticate('facebook', {
scope: ['profile']
}));
router.get('/twitter', passport.authenticate('twitter', {
scope: ['profile']
}));
router.get('/github', passport.authenticate('github', {
scope: ['profile']
}));
router.get('/google/redirect', passport.authenticate('google', {
failureRedirect: '/login'
}), (req, res, next) => {
res.render('profile', {
user: req.user
})
});
router.get('/facebook/redirect', passport.authenticate('facebook', {
failureRedirect: '/login'
}), (req, res, next) => {
res.render('profile', {
user: req.user
})
});
router.get('/twitter/redirect', passport.authenticate('twitter', {
failureRedirect: '/login'
}), (req, res, next) => {
res.render('profile', {
user: req.user
})
});
router.get('/github/redirect', passport.authenticate('github', {
failureRedirect: '/login'
}), (req, res, next) => {
console.log('user details: '+req.user)
res.render('profile', {
user: req.user
})
});
module.exports = router;
Related
When I'm trying to get to http://localhost:7000/logout, the URL redirects me to the main page. And it doesn't sign me out from my Google account. I want to show message "You are logged out" and then I want this code to ask user to log in again.
const express = require('express');
const session = require('express-session');
const passport = require('passport');
require('./auth');
const app = express();
function isLoggedIn(req, res, next) {
req.user ? next() : res.sendStatus(401);
}
app.use(session({ secret: 'cats', resave: false, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.get('/', (req, res) => {
res.send('Authenticate with Google');
});
app.get('/auth/google',
passport.authenticate('google', { scope: [ 'email', 'profile' ] }
));
app.get('/google/callback',
passport.authenticate('google', {
successRedirect: '/protected',
failureRedirect: '/auth/failure',
})
);
app.get('/auth/failure', (req, res) => {
res.send('something went wrong..');
});
app.get('/protected', isLoggedIn, (req, res) => {
res.send(`Hello ${req.user.displayName}`);
});
app.get('/logout', function(req, res, next) {
req.logout(function(err) {
if (err) { return next(err); }
res.redirect("/");
});
});
app.listen(7000, () => console.log('listening on port: 7000'))
I am making a website where users login through Steam. I am able to get their information (such as profile picture and user name) but I've been struggling with sending it back to the client. The json of the user logging in is held within req.user inside of a get request. How would I go about sending the users info from the server to the client of the user that has just logged in?
This is my current code -
// Required to get data from user for sessions
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// Initiate Strategy
passport.use(new SteamStrategy({
returnURL: 'http://localhost:' + port + '/api/auth/steam/return',
realm: 'http://localhost:' + port + '/',
apiKey: 'xxxxxxxxxxxxxxxxxxxx'
}, function (identifier, profile, done) {
process.nextTick(function () {
profile.identifier = identifier;
return done(null, profile);
});
}
));
app.use(session({
secret: 'LoopTrades',
saveUninitialized: true,
resave: false,
cookie: {
maxAge: 3600000
}
}))
app.use(passport.initialize());
app.use(passport.session());
// Routes
app.get('/', (req, res) => {
res.send(req.user);
});
app.get('/api/auth/steam', passport.authenticate('steam', {failureRedirect: '/'}), function (req, res) {
res.redirect('/')
});
app.get('/api/auth/steam/return', passport.authenticate('steam', {failureRedirect: '/'}), function (req, res) {
res.redirect('/pages/deposit.html');
});
i'm trying to put passport logic in controllers file but the problem is when i put the logic inside the controllers it's tell me "Cannot read property 'body' of undefined" but when i move the code to the index routes everything goes right
index.js/controller the problem is in " postLogin "
const User = require('../models/user');
const passport = require('passport');
module.exports = {
async postRegister(req, res, next) {
const newUser = new User({
username: req.body.username,
email: req.body.email,
image: req.body.image
})
await User.register( newUser , req.body.password);
res.redirect('/');
},
postLogin(req, res, next) {
passport.authenticate('local', { successRedirect: '/' ,failureRedirect: '/login' })();
}
}
index.js/routes
const express = require('express');
const router = express.Router();
const { postRegister, postLogin } = require('../controllers/index');
const { errorHandler } = require('../middleware/index');
/* GET home page. */
router.get('/', (req, res, next) => {
res.render('index', { title: 'Surf Shop - Home' });
});
/* User routs */
//Get register
router.get('/register', (req, res, next) => {res.send('/register')});
//POST register
router.post('/register', errorHandler(postRegister));
//Get login
router.get('/login', (req, res, next) => { res.send('GET /Login') });
//POST login
router.post('/login', postLogin);
module.exports = router;
image form postman
Are the brackets intentional at the end of:
passport.authenticate('local', { successRedirect: '/' ,failureRedirect: '/login' })() <----
Issue with parameters not being passed?
router.post('/login', postLogin);
Becomes:
router.post('/login', () => {
postLogin(req, res, next)
});
Correct resolve:
Very helpful but the parameters not being passed here
passport.authenticate('local', { successRedirect: '/' ,failureRedirect: '/login' })(here)
So becomes
`passport.authenticate('local', { successRedirect: '/' ,failureRedirect: '/login' })(req, res, next)`
When I have all of my code in app.js, authenticating with Google works fine, but I tried breaking out the authentication routes in their own files and now I get a connection refused.
//authRouter.js
const express = require("express");
const authRouter = express.Router();
const SECRETS = require("../config/secrets");
const GoogleStrategy = require("passport-google-oauth").OAuth2Strategy;
const passport = require("passport");
passport.use(new GoogleStrategy(SECRETS.google,
(accessToken, refreshToken, profile, done) => {
return done(null, profile);
})
);
authRouter.get("/google", passport.authenticate('google', { scope: ['openid email profile'] }));
authRouter.get("/google/callback",
passport.authenticate("google",
{
failureRedirect: "/login",
successRedirect: "/"
},
(req, res) => {
res.render("hello world"); //successful auth, redirect home, but res is undefined
})
)
module.exports = authRouter;
//app.js
var authConfig = require('./config/secrets'),
express = require('express'),
passport = require('passport'),
TwitterStrategy = require("passport-google-oauth").OAuth2Strategy,
SECRETS = require("./config/secrets"),
authRoutes = require("./routes/authRoutes");
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});
//setup for previously working Google auth
// passport.use(new GoogleStrategy(
// authConfig.google,
// (accessToken, refreshToken, profile, done) => {
// return done(null, profile);
// }
// ));
var app = express();
app.set('view engine', 'hbs');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
app.use(logger('dev'));
app.use(cookieParser());
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static(__dirname + '/public'));
// Application routes
app.get('/', (req, res) => {
res.render('index', {
user: req.user
});
});
app.get('/login', (req, res) => {
res.render('login', {
user: req.user
});
});
//previously working google auth
// app.get('/auth/google',
// passport.authenticate('google', { scope: ['openid email profile'] }));
// app.get('/auth/google/callback',
// passport.authenticate('google', {
// failureRedirect: '/login'
// }),
// (req, res) => {
// // Authenticated successfully
// res.redirect('/');
// });
//**registering authentication routes
app.use("/auth", authRoutes);
app.get('/account', ensureAuthenticated, (req, res) => {
res.render('account', {
user: req.user
});
});
app.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
app.listen(process.env.PORT || 3000, () => {
console.log("Listening...");
});
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next();
}
res.redirect('/login');
}
When I visit the app in a browser where I am logged i to Google, I get a connection refused. I know the credentials are correct, and it's likely some express setup I'm missing. Any thoughts? Thanks in advance.
I'm trying to add user-login module to an existing app in node. It is using separate route files for each module and one main route file to use all the child routes which is ultimately used in server.js
When I try to pass passport instance to the user route, it gives me error as passport is not defined. Here is my app code and structure:
app
views
user
index.ejs
login.ejs
signup.ejs
profile.ejs
routes
docs
index.js
user
index.js
index.js
config
passport.js
server.js
server.js
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const passport = require('passport')
const flash = require('connect-flash')
const session = require('express-session')
const routes = require('./routes/')
const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));
require('./config/passport')(passport);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(session({ secret: '********' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use('/', routes)(app,passport);
const server = app.listen(port, function(){
console.log('Server listening on port '+port);
});
config/passport.js
var LocalStrategy = require('passport-local').Strategy;
const sql = require('mssql')
const bcrypt = require('bcrypt-nodejs')
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function (username, done) {
done(null,username);
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
process.nextTick(function() {
var strSQL = "SELECT count(id) as uCount FROM <tbl> WHERE username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount>0){
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else{
var strSQL1 = "INSERT INTO <tbl>(username, password) VALUES('"+email+"','"+generateHash(password)+"')";
var cb2 = function(err,recordset){
return done(null, recordset,req.flash('signupMessage', 'Email registered successfully.'));
};
executeQuery(strSQL1,'INSERTION','<tbl>',cb2);
}
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
});
}));
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
var strSQL = "SELECT a.count, id, username, password FROM <tbl> c , (SELECT COUNT(dbid) count FROM <tbl> b WHERE b.username = '"+email+"' ) a WHERE c.username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount <= 0){
return done(null, false, req.flash('loginMessage', 'No user found.'));
}
if (!validPassword(password,recordset[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, recordset[0]);
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
}));
};
executeSelection = function(strSQL, operationType, tableName, cb){
var request = new sql.Request(connection);
request.query(strSQL,function(err,recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
cb(err,recordset);
});
};
executeQuery = function(strSQL, operationType, tableName, cb,validateClient) {
var request = new sql.Request(connection);
request.query(strSQL,function(err, recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
if(cb){
cb(validateClient);
}
});
};
generatePasswordHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
validatePassword = function(curPass, dbPass) {
return bcrypt.compareSync(curPass, dbPass);
};
routes/index.js
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs')
const r_user = require('./user') /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res){
res.render('home');
});
module.exports = function(app, passport){
mainroute;
}
routes/user/index.js
const express = require('express')
const router = express.Router()
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', { message: req.flash('loginMessage') });
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile',
failureRedirect : '/login',
failureFlash : true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', { message: req.flash('signupMessage') });
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile',
failureRedirect : '/signup',
failureFlash : true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user : req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
module.exports = function(app, passport) {
router;
}
Please suggest what am I doing wrong here. Thanks
You should wrap your main and user routes to run their logic when you call them and at end return prepared route:
routes/index.js
module.exports = function(app, passport) {
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs');
const r_user = require('./user'); /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res) {
res.render('home');
});
return mainroute;
};
routes/user/index.js
module.exports = function(app, passport) {
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', {
message: req.flash('loginMessage')
});
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', {
message: req.flash('signupMessage')
});
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user: req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
return router;
};
You need to require it at the top of your user/index.js. Simply:
var passport = require('passport');
Then to make sure the user is authenticated:
router.get('/some/path', isLoggedIn, function(req, res) {
var user = req.user;
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}