使用 Express 的 Passport JS,每次都在 'Local' 策略 returns "Missing Credentials" 上进行身份验证
Passport JS using express, authentication on 'Local' strategy returns "Missing Credentials" every time
我的问题是,在 POST 上,每当我尝试使用 'local' 策略进行身份验证时,都会收到 'Missing Credentials' 错误。我最初认为这是 body-parser 的问题,但即使在一些关于强制 urlencoded: true/false 的建议之后,我仍然没有得到任何不同的结果。除了不相关的 req.body 之外,我的控制台日志也没有返回任何实质性内容,我真的不确定此时还能做什么。我已经读到这是特定版本的 Express 的潜在问题,但我已经尝试 downgrading/upgrading 并且没有任何改变。
有一些断点,我在 PassportConfig.js 中的新 localStrategy 似乎从未被调用过,但我不完全确定这是否是我的错误?非常感谢这里的一些指示。
app.js
require("./config/config");
require("./models/db");
require("./config/passportConfig");
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const passport = require("passport");
// router
var rtsIndex = require("./routes/index.router");
var app = express();
// middleware config
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use(passport.initialize());
app.use(passport.session());
app.use("/api", rtsIndex);
我的PassportConfig.js:
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const mongoose = require("mongoose");
var User = mongoose.model("User");
passport.use(
new LocalStrategy({ usernameField: "email" }, (username, password, done) => {
User.findOne({ email: username }, (err, user) => {
if (err) return done(err);
// if user is unknown
else if (!user)
return done(null, false, {
message: "That email address has not been registered"
});
// or if password is wrong
else if (!user.verifyPassword(password))
return done(null, false, { message: "Wrong password" });
// successful authentication
else return done(null, user);
});
})
);
我的基本用户控制器registration/login系统:
const mongoose = require("mongoose");
const passport = require("passport");
const _ = require("lodash");
User = require("../models/user.model");
// snipped some registration code for brevity
module.exports.authenticate = (req, res, next) => {
console.log(req.body);
// call for passport authentication
// executed passport.use from passportConfig
passport.authenticate("local", (err, user, info) => {
// Error from passport middleware
if (err) return res.status(400).json(err);
// user is registered if there is a value in 'user'
else if (user) return res.status(200).json({ token: user.generateJwt() });
// user unkown or wrong password
else return res.status(401).json(info);
})(req, res);
};
编辑:也添加了我的用户模型定义:
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
var userSchema = new mongoose.Schema({
fullName: {
type: String,
required: "Full name cannot be empty"
},
email: {
type: String,
required: "Email cannot be empty",
unique: true
},
password: {
type: String,
required: "Password cannot be empty",
minlength: [4, "Password must be at least 4 characters long"]
},
// Encryption/Decryption of password
saltSecret: String
});
// Custom validation for email
userSchema.path("email").validate(val => {
emailRegex = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return emailRegex.test(val);
}, "Invalid email");
// Events
userSchema.pre("save", function(next) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
// Methods
userSchema.methods.verifyPassword = function(password) {
// plain password, vs encrypted password,
// called from findOne in passportConfig
return bcrypt.compareSync(password, this.password);
};
userSchema.methods.generateJwt = function() {
return jwt.sign({ _id: this._id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXP
});
};
// Can pass custom name as third paramater
// Modified with a force export for debugging
module.exports = mongoose.model("User", userSchema);
最后,一些基本路由:
const express = require("express");
const router = express.Router();
const ctrlUser = require("../controllers/user.controller");
// foreword all links with api/
router.post("/register", ctrlUser.register);
router.post("/authenticate", ctrlUser.authenticate);
// Export router for middleware so app.js can access it
module.exports = router;
对于这些问题,我尝试了以下解决方案:
- Passport js local strategy custom callback "Missing credentials"
- Passport returning "missing credentials" error
由于这不是正文解析器问题,我认为这可能是 usernameField 问题,但似乎也不是这种情况。
我试过你上面提到的代码。
而且我几乎没有做任何更改并删除了一些验证。
我在下面提到所有文件:
passportMiddleware.js
import passportLocal from 'passport-local';
const localStrategy = passportLocal.Strategy;
import userModel from '../model/userModel';
import passport from 'passport';
import bcrypt from 'bcrypt';
passport.use(new localStrategy({
usernameField: 'email',
}, async (email, password, done) => {
const user = await userModel.findOne({ "email": email });
// console.log(user)
if (!user) {
return done(null, false);
}
try {
if (password === user.password) {
return done(null, user)
} else {
return done(null, false, 'password Incorrect')
}
} catch (error) {
return done(error)
}
}));
userController.js
import userModel from '../model/userModel';
import bcrypt from 'bcrypt';
import passport from 'passport';
exports.authenticate = (req, res, next) => {
res.status(200).json({ messaage: 'Authenticated', data: req.user
});
};
userModel.js
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
var userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
}
});
// Events
userSchema.pre("save", function (next) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
module.exports = mongoose.model("Users", userSchema);
routes.js
router.post('/authenticate', passport.authenticate('local', { session: false }), userController.authenticate)
;
试试这个。先导入依赖。
一旦您成功使用 passport-local 进行身份验证。您可以根据您的标准进行更改。
我有 ES6 格式的导入依赖项。您只需将其更改为 ES5。
我的问题是,在 POST 上,每当我尝试使用 'local' 策略进行身份验证时,都会收到 'Missing Credentials' 错误。我最初认为这是 body-parser 的问题,但即使在一些关于强制 urlencoded: true/false 的建议之后,我仍然没有得到任何不同的结果。除了不相关的 req.body 之外,我的控制台日志也没有返回任何实质性内容,我真的不确定此时还能做什么。我已经读到这是特定版本的 Express 的潜在问题,但我已经尝试 downgrading/upgrading 并且没有任何改变。
有一些断点,我在 PassportConfig.js 中的新 localStrategy 似乎从未被调用过,但我不完全确定这是否是我的错误?非常感谢这里的一些指示。
app.js
require("./config/config");
require("./models/db");
require("./config/passportConfig");
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");
const passport = require("passport");
// router
var rtsIndex = require("./routes/index.router");
var app = express();
// middleware config
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
app.use(passport.initialize());
app.use(passport.session());
app.use("/api", rtsIndex);
我的PassportConfig.js:
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const mongoose = require("mongoose");
var User = mongoose.model("User");
passport.use(
new LocalStrategy({ usernameField: "email" }, (username, password, done) => {
User.findOne({ email: username }, (err, user) => {
if (err) return done(err);
// if user is unknown
else if (!user)
return done(null, false, {
message: "That email address has not been registered"
});
// or if password is wrong
else if (!user.verifyPassword(password))
return done(null, false, { message: "Wrong password" });
// successful authentication
else return done(null, user);
});
})
);
我的基本用户控制器registration/login系统:
const mongoose = require("mongoose");
const passport = require("passport");
const _ = require("lodash");
User = require("../models/user.model");
// snipped some registration code for brevity
module.exports.authenticate = (req, res, next) => {
console.log(req.body);
// call for passport authentication
// executed passport.use from passportConfig
passport.authenticate("local", (err, user, info) => {
// Error from passport middleware
if (err) return res.status(400).json(err);
// user is registered if there is a value in 'user'
else if (user) return res.status(200).json({ token: user.generateJwt() });
// user unkown or wrong password
else return res.status(401).json(info);
})(req, res);
};
编辑:也添加了我的用户模型定义:
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
var userSchema = new mongoose.Schema({
fullName: {
type: String,
required: "Full name cannot be empty"
},
email: {
type: String,
required: "Email cannot be empty",
unique: true
},
password: {
type: String,
required: "Password cannot be empty",
minlength: [4, "Password must be at least 4 characters long"]
},
// Encryption/Decryption of password
saltSecret: String
});
// Custom validation for email
userSchema.path("email").validate(val => {
emailRegex = /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return emailRegex.test(val);
}, "Invalid email");
// Events
userSchema.pre("save", function(next) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
// Methods
userSchema.methods.verifyPassword = function(password) {
// plain password, vs encrypted password,
// called from findOne in passportConfig
return bcrypt.compareSync(password, this.password);
};
userSchema.methods.generateJwt = function() {
return jwt.sign({ _id: this._id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXP
});
};
// Can pass custom name as third paramater
// Modified with a force export for debugging
module.exports = mongoose.model("User", userSchema);
最后,一些基本路由:
const express = require("express");
const router = express.Router();
const ctrlUser = require("../controllers/user.controller");
// foreword all links with api/
router.post("/register", ctrlUser.register);
router.post("/authenticate", ctrlUser.authenticate);
// Export router for middleware so app.js can access it
module.exports = router;
对于这些问题,我尝试了以下解决方案:
- Passport js local strategy custom callback "Missing credentials"
- Passport returning "missing credentials" error
由于这不是正文解析器问题,我认为这可能是 usernameField 问题,但似乎也不是这种情况。
我试过你上面提到的代码。 而且我几乎没有做任何更改并删除了一些验证。 我在下面提到所有文件:
passportMiddleware.js
import passportLocal from 'passport-local';
const localStrategy = passportLocal.Strategy;
import userModel from '../model/userModel';
import passport from 'passport';
import bcrypt from 'bcrypt';
passport.use(new localStrategy({
usernameField: 'email',
}, async (email, password, done) => {
const user = await userModel.findOne({ "email": email });
// console.log(user)
if (!user) {
return done(null, false);
}
try {
if (password === user.password) {
return done(null, user)
} else {
return done(null, false, 'password Incorrect')
}
} catch (error) {
return done(error)
}
}));
userController.js
import userModel from '../model/userModel';
import bcrypt from 'bcrypt';
import passport from 'passport';
exports.authenticate = (req, res, next) => {
res.status(200).json({ messaage: 'Authenticated', data: req.user
});
};
userModel.js
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';
import jwt from 'jsonwebtoken';
var userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true,
}
});
// Events
userSchema.pre("save", function (next) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(this.password, salt, (err, hash) => {
this.password = hash;
this.saltSecret = salt;
next();
});
});
});
module.exports = mongoose.model("Users", userSchema);
routes.js
router.post('/authenticate', passport.authenticate('local', { session: false }), userController.authenticate)
;
试试这个。先导入依赖。
一旦您成功使用 passport-local 进行身份验证。您可以根据您的标准进行更改。
我有 ES6 格式的导入依赖项。您只需将其更改为 ES5。