首页 > 解决方案 > 无法让 Passport 与 React 和 Node 一起使用,没有 Passport 身份验证可以正常工作

问题描述

这是我第一次尝试使用 PassportJS,我正在关注他们的文档,这对我来说很难理解。

我的目标是让用户通过注册页面(一个反应组件)进行注册,然后使用登录页面(也是一个反应组件)登录并重定向到仪表板,这也是一个反应组件。

以上所有工作,但没有护照。我不确定我做错了什么,因为这是我第一次使用它,但它似乎不起作用。不工作是指我没有看到任何错误消息,并且登录页面没有重定向到仪表板。

尽管我已经设法将事情几乎放在一起,但不知何故,我要么错过了什么,要么做错了什么。

这是我的 React 登录组件,它正在向 API 发送 Axios 发布请求:

const onSubmit = (e) => {
    e.preventDefault();

    const newLogin = {
      username,
      password,
    };

    const config = {
      headers: {
        'Content-Type': 'application/JSON',
      },
    };

    axios.post('/api/v1/login', newLogin, config).then((res) => {
      return res.data === 'user'
        ? (window.location = '/dashboard')
        : (window.location = '/login');
    });

    setUsername('');
    setPassword('');
  };

在 Node server.js 上,上述登录 post 请求通过路由器发送到控制器。

server.js:

app.use(passport.initialize());
app.use(passport.session());

app.use('/api/v1/register', register);
app.use('/api/v1/login', login);

Router.js(登录):

const { loginUser } = require('../controllers/loginController');

router.route('/').post(loginUser);

登录控制器.js:

require('../config/passport')(passport);

exports.loginUser = (req, res, next) => {
  passport.authenticate('local', {
    successRedirect: '/dashboard',
    failureRedirect: '/register',
    failureFlash: true,
  });
};

这是我的 passport.js 文件:

const User = require('../models/UserModel');
const passport = require('passport');

module.exports = function (passport) {
  passport.use(
    new LocalStrategy((username, password, done) => {
      // Match User
      User.findOne({ username: username })
        .then((err, user) => {
          if (!user) {
            return done(null, false, console.log('no user'));
          }

          //Match Password
          bcrypt.compare(password, user.password, (err, isMatch) => {
            if (err) throw err;

            if (isMatch) {
              return done(null, user);
            } else {
              return done(null, false, { message: 'Password incorrect' });
            }
          });
        })
        .catch((err) => console.log(err));
    })
  );
};

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

passport.deserializeUser((id, done) => {
  User.findOne(id, (err, user) => {
    done(err, user);
  });
});

标签: node.jspassport.jspassport-local

解决方案


我建议从护照登录控制器中删除重定向,并根据应用程序是否在响应中收到用户来在内部(通过反应路由器或其他方式)处理来自反应应用程序的路由。这是我在最近的项目中设置它的方式:

//router.js
const express = require("express");
const fs = require("fs");
const { userModel } = require("../models");
const passport = require("passport");
const bcrypt = require("bcrypt");
const bodyParser = express.urlencoded({ extended: true, limit: "50mb" });
const jsonParser = express.json({ limit: "50mb" });
const router = express.Router();
const saltRounds = 10;

router.get("/login", (req, res) => {
  res.render("login");
});
router.get("/logout", (req, res, next) => {
  req.logout();
  req.session.destroy();
  next();
});
router.post("/login", bodyParser, jsonParser, **passport.authenticate("local"),** (req, res, next) => {
  if (!req.user) return;
  const date = new Date();
  console.log(`User ID:${req.user._id} logged in at ${date}`);
  res.json(req.user);
  next();
});


module.exports = router;

请注意我只是将护照用作中间件,然后转到下一个函数,该函数检查应该从上一个函数接收到的用户


推荐阅读