Passport.js 使用本地身份验证策略抛出 "missing credentials" 错误,即使设置了自定义 usernameField

Passport.js throws "missing credentials" error with local authentication strategy even when custom usernameField is set

我正在尝试实施 passport.js 的本地身份验证策略。我的服务器正在使用快速路由(我相信这可能是问题的原因)。

如果我尝试使用 Axios 在前端传递任何内容,服务器会向我抛出“缺少凭据”错误,即使服务器上的控制台日志显示我收到了正确的数据。

我的主服务器文件:

import express from 'express';
import mongoose from 'mongoose';
import cors from 'cors';
import passport from 'passport';
import cookieParser from 'cookie-parser';
import session from 'express-session';
import authStrategy from "./utils/passportConfig";

// enables ENV variables to be present under command proccess.env
require('dotenv').config();

// enables express.js on the app and defines the port
const app = express();
const port = process.env.PORT || 5000;

// enables CORS - cross origin resource sharing - 
// makes possible requesting resources from another domain
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());

const secret = process.env.SECRET;
app.use(session({
    secret: secret!, 
    resave: true,
    saveUninitialized: true,
}))

app.use(cookieParser(secret));
app.use(passport.initialize());
app.use(passport.session());
authStrategy(passport);


// mongoose helps us connect to our MongoDB database
const uri = process.env.MONGO_URI!;
mongoose.connect(uri, { useNewUrlParser: true, useCreateIndex: true });
const connection = mongoose.connection;
connection.once('open', () => {
    console.log("MongoDB databse connection established successfully");
});

// Routes
const usersRouter = require('./routes/users')(passport);
app.use('/user', usersRouter);

// starts the server, and listens for changes on predefined port
app.listen(port, () => {
    console.log(`Server is running on port: ${port}`);
});

我的护照本地策略配置:

import User, { IUser } from "../models/user.model";
import bcrypt from "bcrypt";
import * as passportLocal from "passport-local";
import { PassportStatic } from "passport";

const localStrategy = passportLocal.Strategy;

export default module.exports = (passport: PassportStatic) => {
    passport.use(
        new localStrategy({
            usernameField: "email",
        },
        (email, password, done) => {
            User.findOne({ email: email.toLowerCase() }).exec()
                .then((user) => {
                    if (!user) {
                        return done(null, false, { message: "User with that email does not exist"});
                    }
                    bcrypt.compare(password, user.password, (err) => {
                        if (err) {
                            return done(null, false, { message: "Incorrect password" });
                        }
                        return done(null, user);
                    })
                })
                .catch((err) => {
                    return done(err);
                })
        })
    )
    passport.serializeUser((req: any, user: any, done: any) => {
        done(null, user.id);
    })
    passport.deserializeUser((id, done) => {
        User.findOne({_id: id}, (err: any, user: any) => {
            done(err, user);
        });
    })
}

我的快递路线处理:

import express from "express";
import { PassportStatic } from "passport";

module.exports = (passport: PassportStatic) => {
    const router = express.Router();
    
    router.route('/login').post( function (req, res, next) {
        console.log("@@@@", req.body)
        passport.authenticate('local', function (err, user, info) {
            console.log("MMMM", err, user, info)
            if (err) { return next(err); }
            if (!user) { return res.status(500).json("User does not exist") }
            req.logIn(user, err => {
                if (err) {
                    return next(err);
                }
                res.status(200).json("Successfully authenticated");
                console.log(req.user);
            })
        })(res, res, next);
    });
    
    return router;
}

什么控制台登录登录路由器return:

@@@@ { email: 'Whosebug@test.com', password: 'fakepassword' }
MMMM null false { message: 'Missing credentials' }

我发现这个问题的所有解决方案都说,Missing credentials 错误是由于护照身份验证策略需要用户名和密码密钥,如果您传递任何其他内容,则需要让护照知道。正如您在护照策略配置文件中看到的那样,我已经做到了。

passport.use(
        new localStrategy({
            usernameField: "email",
        },
        (email, password, done) => {
        ...

这可能是什么问题? server.ts 没有正确传递护照吗? passport 没有使用配置的本地策略吗?

Used packages versions: express: 4.17.1 | express-session: 1.17.1 | passport: 0.4.1 | passport-local: 1.0.0 |

编辑:问题已解决

快速路由处理文件有问题,我在身份验证中间件中传递了两次 `req`。

我已将第一个回复标记为正确,因为这是大多数人在收到 Missing credentials 错误时需要的解决方案。

您似乎在配置护照本地策略时遗漏了password字段。

它必须看起来像这样:

passport.use(
  "local",
  new LocalStrategy(
    {
      usernameField: "email",
      passwordField: "password",
      passReqToCallback: false,  //optional
    },
    async (username, password, done) => {
...