I´m trying to use local authentication with passport. According to the passport doc everything seems easy, but for some reason when I call the passport.authenticate the middleware is not running. Just nothing happens.
When I submit the signup form, the post signup function is called.I got the "Received" in my browser, however, I cannot see any console.log that I have in the passport.use callback.
Server:
const express = require('express');
const morgan = require('morgan');
const expressHandleBars = require('express-handlebars');
const path = require('path');
const flash = require('connect-flash');
const session = require('express-session');
const mysqlStore = require('express-mysql-session');
const passport = require('passport');
const { database } = require('./keys');
// Initializations
const app = express();
require('./lib/passport');
// Setting
app.set('port', process.env.PORT || 4000);
app.set('views', path.join(__dirname, 'views'));
app.engine('.hbs', expressHandleBars({
defaultLayout: 'main',
layoutsDir: path.join(app.get('views'), 'layouts'),
partialsDir: path.join(app.get('views'), 'partials'),
extname: '.hbs',
helpers: require('./lib/handlebars')
}));
app.set('view engine', '.hbs')
// Middleware
app.use(session({
secret: 'whatever',
resave: false,
saveUninitialized: false,
store: new mysqlStore(database)
}));
app.use(morgan('dev'));
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
// Global variables
app.use((req, res, next) => {
app.locals.success = req.flash('success');
next();
});
// Routes
app.use(require('./routes'));
app.use(require('./routes/authentication'));
app.use('/links', require('./routes/links'));
// Public
app.use(express.static(path.join('__dirname', 'public')));
// Starting the server
app.listen(app.get('port'), () => {
console.log('Server on port', app.get('port'));
});
Passport config file (lib/passport.js):
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const pool = require('../database');
const helpers = require('./helpers');
passport.use('local-signup', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, async function(req, username, password, done) {
console.log("Authenticated!!");
console.log(req.body);
}
));
Router calling authenticate (routes/authenticate.js):
const express = require('express');
const passport = require('passport');
const router = express.Router();
router.get('/signup', (req, res) => {
res.render('auth/signup');
});
router.post('/signup', (req, res) => {
passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signupFailure',
failureFlash: true
}, (req, res) => {
res.send("Authenticating");
});
//console.log(req.body);
res.send('Received');
});
router.get('/profile', (req, res) => {
res.send('This is your profile');
});
module.exports = router;
Passport.authenticate() returns a middleware function, you're not calling it.
passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signupFailure',
failureFlash: true
}, (req, res) => {
res.send("Authenticating");
})(req, res)
Related
Hello here I have a server, I am trying to send the user to google auth screen when the path /auth/google is called. But instead I get my 404 screen. I am routing using both express routers and some react routes on the frontend.
Server:
require("dotenv").config();
const express = require("express");
const mongoose = require("mongoose");
var session = require("express-session");
const passport = require("passport");
const path = require("path");
const GoogleStrategy = require("passport-google-oauth20").Strategy;
const app = express();
const port = process.env.PORT || 5000;
app.use(session({
secret: "temp",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
mongoose.connect("mongodb://localhost:27017/bindrake", {useNewUrlParser: true});
//Models
const User = require("./models/user");
const Key = require("./models/key");
//ROUTES
const userRoute = require("./routes/userRoutes");
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
callbackURL: "http://localhost:3000/auth/google/bindrake",
userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo'
},
function(accessToken, refreshToken, profile, cb) {
User.findOrCreate({ googleId: profile.id }, function (err, user) {
return cb(err, user);
});
}
));
app.use(express.json());
app.use(express.urlencoded());
app.use("/api", userRoute);
app.get('/auth/google',
passport.authenticate('google', { scope: ['profile'] }));
if (true){
app.use(express.static("./public/build"));
app.get("*", (req, res) => {
res.sendFile(path.resolve(__dirname, "public", "build", "index.html"));
})
}
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
Is there any idea why, please let me know if you need to see more of the code. Maybe I am doing something wrong while routing it?
Ohh okey, it just worked. I just needed to wait after creating the credentials.
I'm new to Node.js app, and I writing authentication by passport. I can login and authentication routine works fine. However, after post, isAuthenticated() return false and redirect to index page. It seems like the user session is gone after doing post.
Could anybody tell me how to fix it? Here's my code.
app.js
var createError = require('http-errors');
var express = require('express');
const expressLayouts = require('express-ejs-layouts');
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
var flash = require('connect-flash');
const session = require('express-session')
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy
var manageRouter = require('./routes/manage');
var app = express();
app.use(fileUpload());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('tiny'));
app.use(expressLayouts);
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(express.static('public'));
app.use(flash());
app.use(cookieParser('remote_teach'));
app.use(bodyParser.json());
app.use(session({
secret: "remote_teach",
resave: true,
saveUninitialized: true,
cookie: {maxAge: 60 * 60 * 24 * 1000}
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next){
if (req.user && req.isAuthenticated()) {
res.locals["login"] = true;
}
return next();
});
app.use('/manage', manageRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
console.log("404");
next(createError(404));
});
module.exports = app;
route/manage.js
var express = require('express');
var router = express.Router();
var file_system = require('file-system');
var fs = require('fs');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcryptjs');
var md5 = require('md5');
const { encrypt, decrypt, randomString } = require('../crypto');
const db_configure = require('../configure');
var rootDirectory = 'public/data/';
// 資料庫
var mysql = require('mysql');
var connection = mysql.createConnection({
host : db_configure.db_host,
port : db_configure.db_port,
user : db_configure.db_user,
password : db_configure.db_pwd,
database : db_configure.db_name
});
// 顯示登入頁面
router.get('/login', function(req, res, next){
if (req.isAuthenticated()) {
res.redirect('/manage/index');
}else{
res.render('manage/login');
}
});
// Passport JS 登入驗證
passport.use(new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
// Verify Callback
function(req, email, passwd, done) {
//verrify if the user is existed
})
);
passport.serializeUser(function(user, done) {
done(null, user.user_id)
});
passport.deserializeUser(function(id, done) {
//select user and deserialize
done(null, user);
});
router.post('/login', passport.authenticate('local', { successRedirect: '/manage',
failureRedirect: '/',
failureFlash: true})
);
router.post('/user/create', isAuthenticated, function(req, res, next){
var name = req.body.name;
var email = req.body.email;
var password = md5(req.body.password);
connection.query('INSERT INTO users (name, email, password) VALUES (?, ?, ?)',[name, email, password], function (error, results, fields){
if (error){
console.log(error);
}
res.redirect('/manage/users');
});
});
function isAuthenticated(req, res, next) {
if (req.user && req.isAuthenticated()) {
return next();
}
return res.redirect('/');
}
module.exports = router;
In my project I have a report hat is reachable with index.html
But this is private and I want to protect / limit access with my node app. for this I use
app.use('/allure', express.static(path.join(__alluredir , 'allure-report/')));
Then I use for bugging purpose
app.all('/allure/*', function(req, res, next) {
console.log("catched allure query");
next(); // allow the next route to run
});
But the index.html is still reachable with localhost:8080/allure/index.hmtl and also just with localhost:8080/allure/ without an console output. This confuse a lot. Anybody has an idea how to hinder access the index.html without logged in? (Is use passport)
my whole app.js file is:
const express = require('express');
const app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
const expressLayouts = require('express-ejs-layouts');
const mongoose = require('mongoose');
const passport = require('passport');
const flash = require('connect-flash');
const session = require('express-session');
var bodyParser = require('body-parser');
const fs = require('fs');
const path = require('path');
var favicon = require('serve-favicon')
const { allureGenerator } = require('./ops/copyalluredata');
app.set('socketio', io);
//app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ type: 'application/json' }));
app.use(bodyParser.urlencoded({
parameterLimit: 100000,
limit: '50mb',
extended: true
}));
var appDir = path.dirname(require.main.filename);
global.__basedir = appDir;
global.__alluredir = process.env.REPORT_DIR_ENV;
fs.readFile(path.join(appDir, '/config.xml'), (err, data) => {
if (err) throw err;
myConfigData = JSON.parse(data);
process.env.BROWSERSTACK_USERNAME = myConfigData.browserstackid;
process.env.BROWSERSTACK_ACCESS_KEY = myConfigData.browserstackkey;
process.env.BROWSERSTACK_DISPLAY_RESOLUTION="1600x1200";
console.log('config gelesen');
});
//Diese Funktion schreibt die benötigten Dateien in den allure Modul Ordner damit das Logo verwendet wird.
allureGenerator();
// Passport Config
require(path.join(appDir, '/config/passport'))(passport);
// DB Config
var db = '';
if (process.env.NODE_ENV == 'home') {
db = require(path.join(appDir, '/config/keys')).mongoURI;
console.log('keys');
}else{
db = require(path.join(appDir, '/config/keys_local')).mongoURI;
console.log('keys_local');
}
// Connect to MongoDB
mongoose
.connect(
db,
{ useNewUrlParser: true }
)
.then(() => console.log('MongoDB Connected'))
.catch(err => console.log(err));
app.use('/allure', express.static(path.join(__alluredir , 'allure-report/')));
app.use(express.static(appDir));
// EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');
app.set('views', path.join(appDir, '/views'));
app.use(
session({
secret: 'secret',
resave: true,
saveUninitialized: true
})
);
app.use(favicon(path.join(__dirname, 'css', 'fvicon.ico')))
app.use(passport.initialize());
app.use(passport.session());
// Connect flash
app.use(flash());
// Global variables
app.use(function(req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
// Routes
app.use('/', require('./routes/index.js'));
app.use('/users', require('./routes/users.js'));
app.use('/cases', require('./routes/cases.js'));
app.use('/tcafe', require('./routes/tcafe.js'));
app.use('/imgtest', require('./routes/imgtest.js'));
app.use('/rapitest', require('./routes/restapitest.js'));
io.on('connection', function(socket){
console.log('a user connected');
});
app.all('/allure/*', function(req, res, next) {
console.log("catched allure query");
next(); // allow the next route to run
});
app.use((req, res, next) => {
next({
status: 404,
message: 'Not Found',
});
});
app.use((err, req, res, next) => {
if (err.status === 404) {
return res.status(400).render('404',{ layout: 'system.ejs' });
}
if (err.status === 500) {
return res.status(500).render('500');
}
next();
});
const PORT = process.env.PORT || 8080;
http.listen(PORT, console.log(`Server started on port ${PORT}`));
You can use something like this Or just use somemiddleware-
app.use('/allure', function(req,res,next){
if(<authenticate check>){ // some kind of authenticate check
return express.static(path.join(__dirname, 'allure'));
} else {
<Any error you want to show>
}
});
OR
app.use('/allure',<Auth Middlewarae> , express.static(path.join(__dirname, 'allure')));
Trying to use passport-saml connecting to ADFS.
The SAML Response is coming back with Successful status codes.
We get the following success code back:
"<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status>"
But our Passport IsAuthenicated is always generating a false.
I have listed out all of our files used for this below and would appreciate any help.
server.js file:
const express = require('express');
const http = require('http');
const path = require('path');
const passport = require('passport');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require('express-session');
const errorhandler = require('errorhandler');
var env = process.env.NODE_ENV || 'development';
const config = require('./config/config')[env];
console.log('Using configuration', config);
require('./config/passport')(passport, config);
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(cookieParser());
app.enable('trust proxy'); // add this line
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(session(
{
resave: true,
saveUninitialized: true,
secret: 'default',
proxy: true // add this line
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(morgan('combined'));
function ensureAuthenticated(req, res, next) {
if (//req.isAuthenticated()
true
) {
console.log('req.isAuthenticated = ' + req.isAuthenticated());
return next(); }
else{
console.log('req.isAuthenticated = ' + req.isAuthenticated());
res.redirect('/login');
}
}
app.set('port', config.app.port);
require('./config/routes')(app, config, passport);
//ensure that ensureAuthenticated is in the get function call before master build
//ie app.get('/*', ensureAuthenticated, (req, res)
app.use(express.static(path.join(__dirname, 'public')));
app.get('/*', ensureAuthenticated, (req, res) => {
res.sendFile(path.join(__dirname, 'public/index.html'));
});
app.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
routes.js
module.exports = function (app, config, passport) {
app.get('/', function (req, res) {
res.redirect('/home')
});
app.get('/login',
passport.authenticate(config.passport.strategy,
{
successRedirect: '/',
failureRedirect: '/login'
})
);
app.post('/',
passport.authenticate(config.passport.strategy,
{
failureRedirect: '/',
failureFlash: true
}),
function (req, res) {
res.redirect('/');
}
);
app.get('/logout', function (req, res) {
req.logout();
// TODO: invalidate session on IP
res.redirect('https://redrectsite.com/?wa=signout1.0');
});
};
config.js
module.exports = {
development: {
app: {
name: 'Passport SAML strategy example',
port: process.env.PORT || 80
},
passport: {
strategy: 'saml',
saml: {
callbackUrl: process.env.SAML_CALLBACK_URL || 'https://oursite.com',
entryPoint: process.env.SAML_ENTRY_POINT || 'https://oursite.com/adfs/ls/idpinitiatedsignon',
issuer: process.env.SAML_ISSUER || 'https://oursite.com',
identifierFormat: null,
signatureAlgorithm: 'sha256',
authnContext: 'http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/windows',
disableRequestedAuthnContext: true
//cert: process.env.SAML_CERT || null
}
}
}
};
passport.js
const SamlStrategy = require('passport-saml').Strategy;
module.exports = function (passport, config) {
passport.serializeUser(function (user, done) {
done(null, user);
});
passport.deserializeUser(function (user, done) {
done(null, user);
});
passport.use(new SamlStrategy(
{
callbackUrl: config.passport.saml.callbackUrl,
entryPoint: config.passport.saml.entryPoint,
issuer: config.passport.saml.issuer,
cert: config.passport.saml.cert,
identifierFormat: config.passport.saml.identifierFormat,
signatureAlgorithm: config.passport.saml.signatureAlgorithm,
authnContext: config.passport.saml.authnContext,
disableRequestedAuthnContext: config.passport.saml.disableRequestedAuthnContext
},
function (profile, done) {
return done(null,
{
id: profile.uid,
email: profile.email,
displayName: profile.cn,
firstName: profile.givenName,
lastName: profile.sn
});
})
);
};
I had a similar issue. If you look at what isAuthenticated() does, it's actually just checking a property within the request.session object.
https://github.com/jaredhanson/passport/blob/2327a36e7c005ccc7134ad157b2f258b57aa0912/lib/http/request.js#L86
req.isAuthenticated = function() {
var property = 'user';
if (this._passport && this._passport.instance) {
property = this._passport.instance._userProperty || 'user';
}
return (this[property]) ? true : false;
};
I'm not sure if it's passport or express-session, but once you get to the authentication method, the user object is stored at request.session.passport.user so if you like, you can directly verify that it's non-null instead of using the packaged isAuthenticated() method, which seems to check the wrong path.
My code started working after changing it to the following.
if (_.get(req, 'session.passport.user', null)) {
return next();
}
(lodash _.get for easier null-checking of the nested properties)
In my Node app I am using Passport.js Facebook Strategy. I have successfully deplayed my app on heroku and also have made my app public. But only if I login it works. If someone else logs in it promts Internal Server Error.
To check, I checked my mlab database but no data of the logged in user displays.
app.js
const express = require('express');
const exphbs = require('express-handlebars');
const mongoose = require('mongoose');
const passport = require('passport');
const session = require('express-session');
const methodOverride = require('method-override');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
var path = require("path");
// var path = require("path");
//jade
// const jade = require('jade');
//Load Models
require('./models/User');
require('./models/Story');
//Passport config
require('./config/passport')(passport);
//Load Routes
const index = require('./routes/index');
const auth = require('./routes/auth');
const stories = require('./routes/stories');
//Load Keys
const keys = require('./config/keys');
//handlebars helpers
const {
truncate,
stripTags,
formatDate,
select,
editIcon
} = require('./helpers/hbs');
//Load Global Promise
mongoose.Promise = global.Promise;
//Mongoose Connect
mongoose.connect(keys.mongoURI,{
useMongoClient: true,
})
.then(()=>console.log('MongoDB Connected............'))
.catch(err => console.log(err))
const app = express();
// body-parser middleware
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(express.static(path.join(__dirname, '/public')));
app.engine('handlebars', exphbs({
helpers: {
truncate: truncate,
stripTags: stripTags,
formatDate: formatDate,
select: select,
editIcon: editIcon
},
defaultLayout: 'main'
}));
app.set('view engine', 'handlebars');
// app.use(express.static(path.join(__dirname, '/public')));
// app.set('view engine', 'jade');
//Session n cookieParser Middleware
app.use(cookieParser());
app.use(session({
secret: 'secrethaibc',
resave: true,
saveUninitialized: true,
// cookie: {secure: true} //if using https only
cookie: {maxAge: 5*60*60*1000 }, //5 hours of inactivity
rolling: true
}));
//Passport Middleware
app.use(passport.initialize());
app.use(passport.session());
//method-override Middleware
app.use(methodOverride('_method'));
//Set Global vars
app.use((req,res,next) => {
res.locals.user = req.user || null;
next();
});
//Use routes
app.use('/',index);
app.use('/auth',auth);
app.use('/stories',stories);
const port = process.env.PORT || 9000; //process.env.PORT for production port
app.listen(port,()=>console.log(`Server set at ${port}`));
passport.js
const FacebookStrategy = require('passport-facebook').Strategy;
const mongoose = require('mongoose');
const keys = require('./keys');
//Load User model
const User = mongoose.model('users');
module.exports = function(passport){
//FacebookStrategy
passport.use(new FacebookStrategy({
clientID: keys.facebookAppID,
clientSecret: keys.facebookAppSecret,
callbackURL: '/auth/facebook/callback',
profileFields: ['id','displayName','photos','emails'], //did long method could have used 'name'
proxy: true //not sure about this
}, (accessToken, refreshToken, profile, done)=>{
// console.log(accessToken);
// console.log(profile);
const image = `https://graph.facebook.com/${profile.id}/picture?`;
// console.log(image);
const name = profile.displayName.split(' ');
const newUser ={
ID: profile.id,
firstName: name[0],
lastName: name[1],
// firstName: profile.displayName.value.substring(0, profile.displayName.value.indexOf(' ')),
// lastName: profile.displayName.value.substring(profile.displayName.value.indexOf(' '+ 1),),
email: profile.emails[0].value,
image: image
}
// console.log(newUser); for debugging
//Check for existing user
User.findOne({
ID: profile.id
})
.then(user => {
if(user){
//Return User
done(null,user);
}
else{
//Create User
new User(newUser)
.save()
.then(user => done(null,user));
}
})
})
);
//Serialize and Deserialize User
passport.serializeUser((user,done)=>{
done(null,user.id);
});
passport.deserializeUser((id,done)=>{
User.findById(id, (err,user)=>{
done(err,user);
});
});
}
auth.js
const express = require('express');
const router = express.Router();
const passport = require('passport');
//Google Authentication
router.get('/google',
passport.authenticate('google',{scope: ['profile','email'] }));
router.get('/google/callback',
passport.authenticate('google',{ failureRedirect: '/'}),(req,res)=>{
// Successful authentication, redirect home.
res.redirect('/dashboard')
});
//Facebook Authentication
router.get('/facebook',
passport.authenticate('facebook'));
router.get('/facebook/callback',
passport.authenticate('facebook',{failureRedirect:'/'}),(req,res)=>{
// Successful authentication, redirect home.
res.redirect('/dashboard');
});
router.get('/verify',(req,res)=>{
if(req.user){
console.log(req.user);
} else {
console.log('!!!!!!!! Not Auth !!!!!!!!!');
}
});
router.get('/logout',(req,res)=>{
req.logout();
res.redirect('/');
});
module.exports = router;
If you want to try login: App URL