我是一名学生,对 MERN 堆栈和一般用户身份验证仍然非常陌生。我确信这个问题已经被问到了很多,但我一直无法找到答案或弄清楚我的问题。
我一直在尝试使用 Passport、Express 和 Express-session 进行用户身份验证。在之前的非 MERN 项目上,我已经能够让用户身份验证与这些相同的依赖项一起工作,所以我觉得可能结构中的某些东西在这里搞砸了我。我收到了各种各样的错误,但总的来说,似乎 Passport Authentication 中间件没有被执行。
我已经在网上搜索了类似的问题,也搜索了我遇到的所有错误,但仍然被难住了。老师和助教在有限的时间里也搞不清楚。
我真的很感激一些帮助,因为我被困在这里的时间比我想承认的要长。我最近还学习了我开始工作的教程,但该教程包含 server.js 文件中的所有路由。我已经尝试将那个教程重构到我的项目中,但也许我在某个地方搞砸了,因为我的路线被分开了。
我将在下面列出错误以及到目前为止我尝试过的内容。
如果更简单,也欢迎您在 GitHub 上查看整个代码库:Github - Branch
文件结构(我认为是重要的部分)
|- client
|- config
|--- passport.js
|- controllers
|- models
|- routes
|--- API(folder)
|--- applications(this is for interior DB routes)
|--- index
|--- user (these are the user API routes)
|--- index
|- server
服务器文件:
const express = require("express");
const session = require("express-session");
const passport = require('passport');
const cors = require('cors');
const cookieParser = require("cookie-parser");
const bodyParser = require("body-parser")
const routes = require("./routes");
const PORT = process.env.PORT || 3001;
const app = express();
// ============================================
// Middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors({
origin: "http://localhost:3000",
credentials: true
}))
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/build"));
}
app.use(session({ secret: "chimichanga", resave: true, saveUninitialized: true }));
app.use(cookieParser("chimichanga"))
app.use(passport.initialize());
app.use(passport.session());
// Middleware
// ============================================
// Add routes, both API and view
app.use(routes);
// Connect to the Mongo DB
mongoose.connect(process.env.MONGODB_URI || "mongodb://localhost/applyordie");
// Start the API server
app.listen(PORT, function () {
console.log(`? ==> API Server now listening on PORT ${PORT}!`);
});
用户 API 路由 - 我已经尝试了多种方法来要求中间件(更多关于这一点) - 另外,我只包括登录路由,因为这是一个问题出在哪里。
const db = require("../../models/");
const router = require("express").Router();
const userController = require("../../controllers/UserController");
const passport = require('passport');
require("../../config/passport")(passport);
// const localStrategy = require('passport-local').Strategy;
router.post("/login", (req, res, next) => {
passport.authenticate("local", (err, user, info) => {
if (err) throw err;
if (!user) res.send("User does not exist");
else {
req.Login(user, (err) => {
if (err) throw err;
res.send("Successfully Authenticated");
console.log("Successfully Authenticated")
res.redirect("/dashboard");
console.log(req.user);
});
}
})(req, res, next);
})
护照中间件文件:
const User = require("../models");
const bcrypt = require("bcryptjs");
const localStrategy = require('passport-local').Strategy;
module.exports = function (passport) {
passport.use(
new localStrategy((username, password, done) => {
console.log('---- IN PASSPORT ----')
console.log('username: ', username)
console.log('password: ', password)
User.findOne({ username: username }, (err, user) => {
if (err) throw err;
if (!user) return done(null, false);
bcrypt.compare(password, user.password, (err, result) => {
if (err) throw err;
if (result === true) {
return done(null, user);
} else {
return done(null, false);
}
});
});
})
);
// Serialize stores a cookie with the user id
passport.serializeUser((user, cb) => {
cb(null, user.id);
});
// deserialize returns the user cookies, and matches it to a user in the DB
passport.deserializeUser((id, cb) => {
User.findOne({ _id: id }, (err, user) => {
const userInformation = {
username: user.username,
};
cb(err, userInformation);
});
});
};
回调方法尝试 post 方法:
router.post("/login", (req, res, next) => {
passport.authenticate("local", (err, user, info) => {
if (err) throw err;
if (!user) res.send("User does not exist");
else {
req.Login(user, (err) => {
if (err) throw err;
res.send("Successfully Authenticated");
console.log("Successfully Authenticated")
res.redirect("/dashboard");
console.log(req.user);
});
}
})(req, res, next);
})
和
调用中间件:
const passport = require("../../config/passport");
我的日志返回:
Client Console: POST 500 (Internal Server Error)
Server Console: TypeError: passport.authenticate is not a function
所以尝试调用中间件:
const passport = require('passport');
require("../../config/passport")(passport);
但是这个版本没有返回任何错误,也没有点击我放在 Passport 文件中的控制台日志,所以似乎 Passport.authenticate 根本没有运行。
我也试过在 POST 调用中使用中间件方法
router.post("/login", passport.authenticate("local",
{
successRedirect: "/dashboard",
failureRedirect: "/",
}
// ), function (req, res, next) {
), function (req, res) {
console.log("/login request.body: ", req.body)
console.log('///// Sign In Success ////');
console.log('REQ SESSION', req.session)
console.log('REQ USER', req.user)
res.json(req.user);
});
充其量我得到了:
Client: 500 Internal Server Error
Server: Proxy error: Could not proxy request /api/user/login from localhost:3000 to http://localhost:3001/.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).