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) => {
...
我正在尝试实施 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) => {
...