node.js - Nodejs 身份验证

标签 node.js authentication express passport.js strategy-pattern

我正在做一个nodejs web程序,我需要本地身份验证,谷歌和facebook。对于谷歌和 Facebook,我还没有 DNS 来成功返回。 当我进行本地身份验证时,服务器不断思考并说他们没有响应。 这是我的 server.js:(请帮助我)

var express = require('express'),
flash = require('connect-flash')
exphbs = require('express-handlebars'),
logger = require('morgan'),
cookieParser = require('cookie-parser'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
session = require('express-session'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy,
mongoose = require('mongoose');
GoogleStrategy = require('passport-google').Strategy,
FacebookStrategy = require('passport-facebook').Strategy,
LocalStrategy = require('passport-local').Strategy
Schema = mongoose.Schema,
bcrypt = require('bcrypt'),
util = require('util')
SALT_WORK_FACTOR = 10;
FACEBOOK_APP_ID = "944091472291356"
FACEBOOK_APP_SECRET = [removed];
User = require('./models/user.js');
login = require('./views/layouts/userlogin');
signin = require('./views/signin');
var Auth0Strategy = require('passport-auth0');
 auth = require('basic-auth');
mysql = require('mysql')


//Creating connection to data base
var config = require('./config.js'), //config file contains all tokens and other private info
funct = require('./functions.js'), //funct file contains our helper functions for our Passport and database work
app = express();
//Base de dados mongo
module.exports = mongoose.model('User', UserSchema);
mongoose.connect("mongodb://localhost:27017/MyDatabase", function(err, db){
if( !err ){
console.log("Ligado ao servidor mongoDB");
} else console.log(err);
});

UserSchema = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};


var Schema = mongoose.Schema;
var UserDetail = new Schema({
username: String,
password: String
}, {
collection: 'userInfo'

});

var ricardo = new User ({
username : 'ricardo',
password : 'rolo',
hasCreditCookie: true
});


var UserDetails = mongoose.model('userInfo', UserDetail);
//We will be creating these two files shortly
var config = require('./config.js'), //config file contains all tokens and other private info
funct = require('./functions.js'); //funct file contains our helper functions for our Passport and database work
var UserSchema = new Schema({
username: { type: String, required: true, index: { unique: true } },
password: { type: String, required: true }
});
UserSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
function findById(id, fn) {
var idx = id - 1;
if (users[idx]) {
fn(null, users[idx]);
} else {
fn(new Error('User ' + id + ' does not exist'));
}
}
function findByUsername(username, fn) {
for (var i = 0, len = users.length; i < len; i++) {
var user = users[i];
if (user.username === username) {
return fn(null, user);
}
}
return fn(null, null);
}
var UserDetails = mongoose.model('userInfo', UserDetail);
//new schema
var Schema = mongoose.Schema;
var UserDetail = new Schema({
username: String,
password: String
}, {
collection: 'userInfo'
});

////////////////////////////////Local - PASSPORT by:zezão xD

passport.use(new LocalStrategy(function(username,password,done){
   connection.query("select * from BdClientes.Users where username='"+username+"'     ",function(err,user){
    if(err)
    {
        return done(err);           
    }
    if(!user)
    {
        return done(null,false,{message: 'Incorrect user name'});           
    }
    if(user.password != password)
    {
       return done(null,false,{message: 'Incorrect password'});
    }

    return done(null,user);     

   });
}
));
app.post('/home', passport.authenticate('signin',{successRedirect: '/home', failureRedirect: '/signin', failureFlash: true }));

passport.serializeUser(function(user, done) {
  done(null, user._id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function(err, user) {
    done(err, user);
  });
});

// passport/signin.js
passport.use('local-signin', new LocalStrategy({
    username : 'username',
    password : 'password',
    passReqToCallback : true
  },
  function(req, username, password, done) {
    // verifica no mongo se o nome de usuário existe ou não
    User.findOne({ 'username' :  username },
      function(err, username) {
        // Em caso de erro, retorne usando o método done
        if (err)
          return done(err);
        // Nome de usuário não existe, logar o erro & redirecione de volta
        if (!user){
          console.log('Usuário não encontrado para usuário '+username);
          return done(null, false,
                req.flash('message', 'Usuário não encontrado.'));
        }
        // Usuário existe mas a senha está errada, logar o erro
        if (!isValidPassword(user, password)){
          console.log('Senha Inválida');
          return done(null, false,
              req.flash('message', 'Senha Inválida'));
        }
        // Tanto usuário e senha estão corretos, retorna usuário através
        // do método done, e, agora, será considerado um sucesso
        return done(null, user);
      }
    );
}));



//LOCAL signin
passport.use('local-signin', new LocalStrategy({
usernameField : 'username',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, username, password, done) {
process.nextTick(function() {
User.findOne({ 'local.username' : username }, function(err, user) {
if (err)
return done(err);
if (user) {
return done(null, false, req.flash('signinMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
process.nextTick(findOrCreateUser);
}));



// Use the LocalStrategy within Passport to register/"signin" users.
passport.use('signin', new LocalStrategy(
{passReqToCallback : true}, //allows us to pass back the request to the callback
function(req, username, password, done) {
funct.signin(username, password)
.then(function (user) {
if (user) {
console.log("REGISTERED: " + user.username);
req.session.success = 'You are successfully registered and logged in ' + user.username + '!';
done(null, user);
}
if (!user) {
console.log("COULD NOT REGISTER");
req.session.error = 'That username is already in use, please try a different one.'; //inform user could not log them in
done(null, user);
}
})
.fail(function (err){
console.log(err.body);
});
}
));
// Simple route middleware to ensure user is authenticated.
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
req.session.error = 'Please sign in!';
res.redirect('/signin');
}
////FACEBOOK PASSPORT
passport.use(new FacebookStrategy({
clientID: FACEBOOK_APP_ID,
clientSecret: FACEBOOK_APP_SECRET,
callbackURL: "http://localhost:5000/auth/facebook/callback"
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function () {
return done(null, profile);
});
}
));
//GOOGLE
passport.use(new GoogleStrategy({
returnURL : 'http://127.0.0.1:5000/auth/google',
realm: 'http://127.0.0.1:5000/'
},
function(identifier, profile, done) {
User.findOrCreate({ openId: identifier }, function(err, user) {
done(err, user);
});
}
));
////////////////////////////////////////EXPRESS
// Configure Express
app.use(logger('combined'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(methodOverride('X-HTTP-Method-Override'));
app.use(session({secret: 'supernova', saveUninitialized: true, resave: true}));
app.use(passport.initialize());
app.use(passport.session());
// Configure express to use handlebars templates
var hbs = exphbs.create({
defaultLayout: 'main', //we will be creating this layout shortly
});
app.engine('handlebars', hbs.engine);//handlebars templates
app.set('view engine', 'handlebars');//
//// app.set('view engine', 'ejs');//EJS templates
//app.use(app.mountpath);
// Session-persisted message middleware
app.use(function(req, res, next){
var err = req.session.error,
msg = req.session.notice,
success = req.session.success;
delete req.session.error;
delete req.session.success;
delete req.session.notice;
if (err) res.locals.error = err;
if (msg) res.locals.notice = msg;
if (success) res.locals.success = success;
next();
});
//Requerido para o passport
app.use(session({ secret: 'eutentoetento' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session




///////////////////////////////////////////ROUTES
//displays our homepage
app.get('/', function(req, res){
res.render('./home', {user: req.user});
});
//login//
app.get('/login', function(req, res) {
res.render('login', { user: req.user, message: req.flash('error') });
});
//sends the request through our local login/signin strategy, and if successful takes user to homepage, otherwise returns then to signin page
app.post('/login', function(req, res, next) {
   passport.authenticate('home', function(err, user, info) {

   // Error Check
   if(err) { return next(err);
 }
   // Json Response reflecting authentication status
   if(!user) { 
      return res.send({success:false, message: 'authentication failed '})
   }
   // Success
   return res.send({succes:true, message: 'authentication succeeded'}) 
  })
})



//SIGNIN//
app.get('/signin', function(req, res){
res.render('signin', { message: req.flash('signinMessage') });;
});
app.post('/signin', passport.authenticate('local-signin', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signin', // redirect back to the signin page if there is an error
failureFlash : true // allow flash messages
}));
//PROFILE
app.get('profile', isLoggedIn, function(req, res) {
res.render('profile', {
user: req.user // tira o user da sessao e passa para o template
});
});
//LOGOUT
//logs user out of site, deleting them from the session, and returns to homepage
app.get('/logout', function(req, res){
var name = req.user.username;
console.log("LOGGIN OUT " + req.user.username)
req.logout();
res.redirect('/');
req.session.notice = "You have successfully been logged out " + name + "!";
});
//FB
app.use(session({ secret: 'keyboard cat' }));
app.get('/auth/facebook',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/');
});
<pre>
//google routes//
app.get('/auth/google', passport.authenticate('google'));
app.get('/auth/google/return',
passport.authenticate('google', { successRedirect: '/',
failureRedirect: '/login' }));
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
//////////////////////////////////LAUCH
//===============PORT=================
var port = process.env.PORT || 5000; //select your port or let it pull from your .env file
app.listen(port);
console.log("listening on " + port + "!");
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login');
}

最佳答案

由于您已经使用 Passport.js对于本地身份验证,您应该查看其插件(称为策略)以使用 OAuth 或 OpenID 连接到不同的服务,包括 Facebook , Twitter ,和GoogleHere是一个非常好的教程(with updates for express 4.0),它解释了如何进行这些类型的身份验证。

另外,为了清楚起见,我建议将这些架构放在自己的文件中。

关于node.js - Nodejs 身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28984320/

相关文章:

node.js - 如何枚举nodejs+express中的所有 session ?

node.js - NodeJS/Express 不是异步的

node.js - Nodejs : Performance issues parsing CSV and Zip

node.js - MongoDB 设置数据库脚本(基于 NodeJS 的项目)

javascript - 如何在 NodeJs 终端中使用 await?

Api token 身份验证 - 通过参数或 header ?

c++ - 使用 OCI 的 Oracle Wallet 身份验证

authentication - 登录后如何使用用户详细信息?

javascript - 将逗号分隔的数字字符串转换为数字

model-view-controller - 这是使用 MVC 模式和 Express.js 的好方法吗?