在本地,Auth 有效。在部署时登录,但 Auth 返回 False
Locally, Auth works. on Deployment, logs in, but the Auth gets returned False
本地这个
module.exports.isAuth = (req, res, next) => {
if (req.isAuthenticated()) {
next();
// res.status(200).json({ user: req.user, auth: true });
} else {
return res.status(401).json({ auth: false, msg: "Here" });
}
};
完美运行,我登录了。
但是当我尝试在 Heroku 上而不是在本地使用后端执行此操作时,我将“Else”返回到前端。
问题是我知道问题出在哪里,很可能,我只是觉得我在一个空房间里寻找它。
我得到了前端返回的 Json 对象,即使我的 passport 中间件在服务器上记录为“已登录”。这是护照中间件
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const connection = require("./database");
const mongoose = require("mongoose");
const User = mongoose.models.User;
const validPassword = require("../lib/passwordUtils").validPassword;
const cors = require("cors");
passport.use(
cors({
origin: [
"http://2607:fb90:b6e0:a363:f89f:be4b:a976:9ed0:3001",
"https://frontendfullstack.netlify.app",
"http://localhost:3001",
"localhost:3001",
],
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
})
);
const customFields = {
usernameField: "username",
passwordField: "password",
};
passport.use(
new LocalStrategy(customFields, (username, password, done) => {
User.findOne({ username: username })
.then((user) => {
if (!user) {
console.log("No user");
return done(null, false);
} else {
const isValid = validPassword(password, user.hash, user.salt);
if (isValid) {
console.log("Logged in");
return done(null, user);
} else {
console.log("Wrong Password");
return done(null, true);
}
}
})
.catch((err) => {
done(err);
});
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
}).catch((err) => done(err));
});
重申一下,当服务器在本地时,它可以正常工作,我登录并重定向后,网站就可以完美运行。
问题在于Passport Local Strategy使用cookies进行身份验证,而Heroku只允许为自己的域设置cookies。
由于您的前端托管在 Netlify 中,如果您检查开发人员工具,您会发现没有设置 cookie。因此,您在登录后发出的下一个请求将失败。
除了在 Heroku 中同时托管后端和前端外,您无能为力,这样您的应用程序才能正常工作。
我前几天回答过类似的问题,最后留下了一些提示:
编辑:
好的,让我们看看是否可以完成这项工作。我没有使用过 React,但构建生产应用程序的过程与我读到的 Angular 有点相似。
首先,您需要恢复到您的应用正常运行的先前提交。然后创建一个新分支(即 backup
),以确保如果出现任何问题,您可以恢复到它。现在,再次结账到您的 main
。这是因为 Heroku 将忽略从非 main
分支推送的提交。
在你的 React 应用程序项目文件夹上执行 npm run build
,你将在 build
文件夹中获得编译文件。在那里您会找到 index.html
文件,在 build/static
文件夹中您会找到所有 .js 和 .css 文件,这些文件的哈希名称包含您的应用程序代码。
根据生成此 build
文件夹的位置,您可能需要手动复制它,以便它最终成为 Express 项目文件夹树中的一个文件夹。
确保新文件夹未被忽略(检查 .gitignore
文件),以便它将包含在您将进行的下一次提交中。
在设置您的 Express 服务器的文件中(app.js
、server.js
或任何您命名的文件),在设置路由的部分,您需要添加此行:
app.use(express.static(path.join(__dirname, 'build')));
这一行将确保当您尝试访问 /
路径时,Express 会将 index.html
文件发送给客户端。因此,它就像托管在 Netlify 中一样。
现在,您可以 git add .
-> git commit -m 'Deploy test message'
-> git push heroku main
。
如果一切顺利,您现在可以访问 Heroku 分配给您的应用程序的 URL,您会在那里看到您的前端服务。
根据您的文件夹或环境变量,您可能 运行 遇到其他一些问题,但这应该可以。
告诉我。
本地这个
module.exports.isAuth = (req, res, next) => {
if (req.isAuthenticated()) {
next();
// res.status(200).json({ user: req.user, auth: true });
} else {
return res.status(401).json({ auth: false, msg: "Here" });
}
};
完美运行,我登录了。
但是当我尝试在 Heroku 上而不是在本地使用后端执行此操作时,我将“Else”返回到前端。
问题是我知道问题出在哪里,很可能,我只是觉得我在一个空房间里寻找它。
我得到了前端返回的 Json 对象,即使我的 passport 中间件在服务器上记录为“已登录”。这是护照中间件
const passport = require("passport");
const LocalStrategy = require("passport-local").Strategy;
const connection = require("./database");
const mongoose = require("mongoose");
const User = mongoose.models.User;
const validPassword = require("../lib/passwordUtils").validPassword;
const cors = require("cors");
passport.use(
cors({
origin: [
"http://2607:fb90:b6e0:a363:f89f:be4b:a976:9ed0:3001",
"https://frontendfullstack.netlify.app",
"http://localhost:3001",
"localhost:3001",
],
credentials: true,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
})
);
const customFields = {
usernameField: "username",
passwordField: "password",
};
passport.use(
new LocalStrategy(customFields, (username, password, done) => {
User.findOne({ username: username })
.then((user) => {
if (!user) {
console.log("No user");
return done(null, false);
} else {
const isValid = validPassword(password, user.hash, user.salt);
if (isValid) {
console.log("Logged in");
return done(null, user);
} else {
console.log("Wrong Password");
return done(null, true);
}
}
})
.catch((err) => {
done(err);
});
})
);
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
User.findById(id, (err, user) => {
done(err, user);
}).catch((err) => done(err));
});
重申一下,当服务器在本地时,它可以正常工作,我登录并重定向后,网站就可以完美运行。
问题在于Passport Local Strategy使用cookies进行身份验证,而Heroku只允许为自己的域设置cookies。
由于您的前端托管在 Netlify 中,如果您检查开发人员工具,您会发现没有设置 cookie。因此,您在登录后发出的下一个请求将失败。
除了在 Heroku 中同时托管后端和前端外,您无能为力,这样您的应用程序才能正常工作。
我前几天回答过类似的问题,最后留下了一些提示:
编辑:
好的,让我们看看是否可以完成这项工作。我没有使用过 React,但构建生产应用程序的过程与我读到的 Angular 有点相似。
首先,您需要恢复到您的应用正常运行的先前提交。然后创建一个新分支(即
backup
),以确保如果出现任何问题,您可以恢复到它。现在,再次结账到您的main
。这是因为 Heroku 将忽略从非main
分支推送的提交。在你的 React 应用程序项目文件夹上执行
npm run build
,你将在build
文件夹中获得编译文件。在那里您会找到index.html
文件,在build/static
文件夹中您会找到所有 .js 和 .css 文件,这些文件的哈希名称包含您的应用程序代码。根据生成此
build
文件夹的位置,您可能需要手动复制它,以便它最终成为 Express 项目文件夹树中的一个文件夹。确保新文件夹未被忽略(检查
.gitignore
文件),以便它将包含在您将进行的下一次提交中。在设置您的 Express 服务器的文件中(
app.js
、server.js
或任何您命名的文件),在设置路由的部分,您需要添加此行:
app.use(express.static(path.join(__dirname, 'build')));
这一行将确保当您尝试访问 /
路径时,Express 会将 index.html
文件发送给客户端。因此,它就像托管在 Netlify 中一样。
现在,您可以 git add .
-> git commit -m 'Deploy test message'
-> git push heroku main
。
如果一切顺利,您现在可以访问 Heroku 分配给您的应用程序的 URL,您会在那里看到您的前端服务。
根据您的文件夹或环境变量,您可能 运行 遇到其他一些问题,但这应该可以。
告诉我。