Как настроить PassportJS для бэкэнд-аутентификации? - PullRequest
0 голосов
/ 24 марта 2019

Так что, прочесывая интернет последние 60 часов подряд, я решил опубликовать вопрос на SO.

В настоящее время я пытаюсь создать приложение React. Он структурирован таким образом, что под /client находится весь код реакции (на localhost:3000), а /server обрабатывает все запросы api в дополнение к аутентификации (на localhost:5000). (С использованием стека MERN)

Сейчас я действительно изо всех сил пытаюсь заставить PassportJS работать. Я полностью прочитал документацию, представленную здесь: http://www.passportjs.org/docs/ в дополнение к примеру с использованием Местной стратегии, представленному здесь: https://github.com/passport/express-4.x-local-example/blob/master/server.js

Моя проблема сейчас заключается в том, что первоначальная аутентификация (POST запрос с учетными данными) проходит нормально. Тем не менее, я считаю, что serializeUser не сериализует user.id внутри session (но определенно вызывается!). При выводе req.session получаю:

Session {
  cookie:
   { path: '/',
     _expires: null,
     originalMaxAge: null,
     httpOnly: true,
     secure: false } }

Однако, похоже, что-то работает, потому что если я смотрю в req.sessionStore.sessions, я вижу куки с 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"}}'
}

Эти файлы cookie сохранялись при обновлении страницы, пока сервер не перезапустится.


Я не совсем уверен, какой код предоставить, но я могу добавить дополнительные фрагменты, если это необходимо.

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();
  });
};

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}`));

Я понимаю, что это не самый воспроизводимый код, но любая помощь или совет будут высоко оценены. Я также могу отредактировать вопрос, чтобы сделать его более доступным !!


РЕДАКТИРОВАТЬ 1

Так что теперь я могу получить user.id внутри сессии. Я сделал это, изменив мой оператор cors на app.use(cors({credentials: true, origin: 'http://localhost:3000'})); и затем предоставив учетные данные с запросами POST и GET. К сожалению, я все еще не получаю аутентификацию даже с user подарком.


РЕДАКТИРОВАТЬ 2

Я исправил функцию deserializeUser в приведенном выше коде

1 Ответ

0 голосов
/ 24 марта 2019

Я не знаю, что вы пропустили, но вот этот код конфигурации паспорта, который работал для меня в недавнем проекте:

Конфигурация паспорта в 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'
  })
);

Надеюсь, это поможет, С уважением.

...