如何设置PassportJS进行后端身份验证?

时间:2019-03-24 02:42:25

标签: javascript node.js express session passport.js

因此,在最近60个小时内一直上网搜索后,我决定在SO上发布一个问题。

目前,我正在尝试构建一个React应用程序。它的结构使得在/client下是所有反应代码(在localhost:3000处),而/server处理除认证(在{{ 1}})。 (使用MERN堆栈)

现在,我真的很努力地尝试使PassportJS正常工作。除了使用此处提供的使用本地策略的示例之外,我还仔细阅读了此处提供的文档:http://www.passportjs.org/docs/https://github.com/passport/express-4.x-local-example/blob/master/server.js

我现在的问题是初始身份验证(带有凭据的api请求)通过得很好。但是,我相信localhost:5000不会在POST内部对serializeUser进行序列化(但肯定会被调用!)。输出user.id时,我得到:

session

但是,某些事情似乎确实起作用了,因为如果我查看req.session,就会看到带有Session { cookie: { path: '/', _expires: null, originalMaxAge: null, httpOnly: true, secure: false } } 的Cookie:

req.sessionStore.sessions

除非重新启动服务器,否则这些cookie似乎会在页面刷新期间保留。


我不确定要提供什么代码,但是如有必要,我可以添加其他代码段。

user.id

{ 'mxsYcA2DrYVz4E5q-BiBbw8_810Slj-2':
         '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
           "passport":{"user":"5c93f9a655f8a740f732a9c1"}}',
        'hW_cvQeJLk7JpLxK7TZVzIMuOEMi6-6w':
         '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
           "passport":{"user":"5c93f9a655f8a740f732a9c1"}}',
        '7_2AWWdijpVVl6OFrmauorBt1Q4crBGa':
         '{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},
           "passport":{"user":"5c93f9a655f8a740f732a9c1"}}'
}

passport.js

var mongoose = require('mongoose');
var User = mongoose.model('User');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;

function verifyPassword(user, password) {
  return (user.password == password);
}

passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function (err, user) {
      if (err) {
        return done(err);
      } else if (!user) {
        return done(null, false);
      } else if (!verifyPassword(user, password)) {
        return done(null, false);
      } else {
        return done(null, user);
      }
    });
  }
));

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

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

AuthRoutes.js

var passport = require('passport');

module.exports = function(app) {
  app.post('/auth', passport.authenticate('local', {
    successRedirect: '/success',
    failureRedirect: '/invalid'
  }));

  app.get('/auth', passport.authenticate('local', {
    successRedirect: '/success',
    failureRedirect: '/invalid'
  }));

  app.get('/success', function(req, res) {
    console.log('success');
    console.log(req.session);
    res.sendStatus(200);
  });

  app.get('/invalid', function(req, res) {
    console.log('invalid');
    console.log(req.session);
    res.sendStatus(403);
  });

  app.get('/logout', function(req, res) {
    req.logout();
  });
};

我知道这不是最可重复的代码,但是任何帮助或建议都将不胜感激。我可以编辑问题以使其更易于访问!


编辑1

因此,我现在可以在会话中获得server.js。为此,我将const express = require('express'); const process = require('process'); const mongoose = require('mongoose'); const bodyParser = require('body-parser'); const session = require('express-session'); const passport = require('passport'); const cors = require('cors'); const app = express(); // Prevents CORS issues app.use(cors()); // Decides Port const port = process.env.PORT || 5000; // MongoDB const User = require('./api/models/UserModel'); const db_name = "testdb"; mongoose.Promise = global.Promise; mongoose.connect(process.env.MONGODB_URI+"/"+db_name); app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json()); app.use(session({ secret: 'this_is_my_secret_salt', resave: false, saveUninitialized: true, cookie: {secure: true} })); require("./config/passport"); app.use(passport.initialize()); app.use(passport.session()); // Add Auth Routes var authRoutes = require('./api/routes/AuthRoutes'); authRoutes(app); // console.log that your server is up and running app.listen(port, () => console.log(`Listening on port ${port}`)); 语句更改为user.id,然后为corsapp.use(cors({credentials: true, origin: 'http://localhost:3000'}));请求提供了凭据。不幸的是,即使有POST,我仍然没有得到认证。


编辑2

我已更正了上面代码中的GET函数

1 个答案:

答案 0 :(得分:0)

我不知道您错过了什么,但是下面的护照配置代码在最近的项目中对我有用:

app.js中的护照配置:

const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const User = require('./models/User');

// Passport configuration
app.use(
  require('express-session')({
    cookie: { maxAge: 43200000 },
    secret: 'secret',
    resave: false,
    saveUninitialized: true
  })
);
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

User.js中的用户模型:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const passportLocalMongoose = require('passport-local-mongoose');

const User = new Schema({
  username: {
    type: String,
    required: true
  },
  password: {
    type: String,
    required: true
  },
  isAdmin: {
    type: Boolean,
    default: false
  }
});

User.plugin(passportLocalMongoose);

module.exports = mongoose.model('User', User);

验证路由:

// @route   POST /register
// @desc    Register new user
// @access  Public
router.post('/register', (req, res) => {
  const newUser = new User({
    username: req.body.username
  });
  User.register(newUser, req.body.password, (err, user) => {
    if (err) {
      res.redirect('/register'); //failure redirect
    }
    passport.authenticate('local')(req, res, () => {
      res.redirect('/programs'); //success redirect
    });
  });
});

// @route   POST /login
// @desc    
// @access  Public
router.post(
  '/login',
  passport.authenticate('local', {
    successRedirect: '/programs',
    failureRedirect: '/login'
  })
);

希望这会有所帮助, 问候。