护照不保存会话

Passport doesn't save the session

我已经阅读了很多关于这个问题的资料,但任何答案都不适合我。我正在使用 React、Express 和 Passport 来管理我的身份验证例程。身份验证例程很好,它进行了我想要的重定向。但是,当我刷新任何路线时,它说我没有通过身份验证。似乎 Passport 没有保存会话。这是我的代码:

Server.js

const lisaApp = express();

lisaApp.use(bodyParser.json())
lisaApp.use(bodyParser.urlencoded({ extended: false }))
lisaApp.use(cookieParser())
lisaApp.use(session({
  secret: config.secret,
  resave: false,
  saveUnitialized: false
}))
lisaApp.use(passport.initialize())
lisaApp.use(passport.session())

passport.use(auth.localStrategy);
passport.serializeUser(auth.serializeUser);
passport.deserializeUser(auth.deserializeUser);

lisaApp.post('/login', (req, res, next) => {
  const validationResult = validateLoginForm(req.body);
  if (!validationResult.success) {
    return res.status(400).json({
      success: false,
      message: validationResult.message,
      errors: validationResult.errors
    });
  }

  return passport.authenticate('local', (err, userData) => {
    if (err) {
      if (err.response.statusText === 'Unauthorized') {
        return res.status(400).json({
          success: false,
          message: 'The password is not right'
        });
      }

      return res.status(500).json({
        success: false,
        message: 'Wrong data'
      });
    }

    console.log('is authenticated?: ' + req.isAuthenticated()) // Here always is false

    return res.json({
      success: true,
      token,
      message: 'Successful Login',
      user: userData.data
    });
  })(req, res, next);
});

// I am using this function as a middleware to check if the user is authenticated, always is false. No matter if I put right data in the login form
function ensureAuth (req, res, next) {
  if (req.isAuthenticated()) {
    return next();
  }

  res.status(401).send({ error: 'not authenticated' })
}

auth/index.js(护照套路)

var LocalStrategy = require('passport-local').Strategy;
var LisaClient = require('pos_lisa-client');
var config = require('../config');

var ClientApi = LisaClient.createClient(config.lisaClient);

exports.localStrategy = new LocalStrategy({
  usernameField: 'username',
  passwordField: 'password',
  session: false,
  passReqToCallback: true
}, (req, username, password, done) => {
  var authData = {
    username,
    password
  }

  // Here is a custom API, I pass the data that I need. This works fine
  ClientApi.authenticate(authData, (err, token) => {
    if (err) {
      return done(err)
    }

    var token = token.data

    ClientApi.getClient(username, (err, user) => {
      if (err) {
        return done(err)
      }

      user.token = token
      return done(null, user)
    })
  })
})


exports.serializeUser = function (user, done) {
// The app never enters here
  done(null, {
    username: user.username,
    token: user.token
  })
}

exports.deserializeUser = function (user, done) {
// The app never enters here
  ClientApi.getClient(user.username, (err, usr) => {
    if (err) {
      return done(null, err)
    } else {
      usr.token = user.token
      done(null, usr)
    }
  })
}

我哪里错了?

如果您使用的是自定义身份验证回调,则必须调用 req.logIn() 来建立会话(或者您可以手动创建会话):

// Add this where you are console.log'ing `req.isAuthenticated()`

req.logIn(userData, function(err) {
  if (err) return next(err);

  console.log('is authenticated?: ' + req.isAuthenticated());

  return res.json({
    success: true,
    token,
    message: 'Successful Login',
    user: userData.data
  });
});

这已记录在案 here(向下滚动到 "Custom Callback"):

Note that when using a custom callback, it becomes the application's responsibility to establish a session (by calling req.login()) and send a response.