reactjs - Passport.js isAuthenticated() 在 heroku 上总是返回 false,但在本地运行服务器时正常工作
问题描述
我正在使用 passport.js 进行身份验证以及快速会话在客户端上存储 cookie。此外,我的客户是一个反应应用程序。我仍然不确定这是服务器端问题还是客户端问题。无论如何,当我在本地运行我的节点服务器,然后从我的 react 应用程序登录时,cookie 存储在本地并且我已通过身份验证,因此如果我访问需要身份验证的路由,我将获得访问权限。但是,当我在 Heroku 和相同的 react 应用程序上运行相同的服务器代码时,我从 React 应用程序登录,护照。验证工作并将成功消息发送回客户端但是由于某种原因现在如果我访问受保护的路由,我的服务器无法验证客户端。我知道 cookie 已存储,因为一旦我切换到本地服务器,我就会再次通过身份验证,这意味着 cookie 与客户端一起存在。我'
Node.js 服务器代码BACKEND
const app = express();
mongoose.connect("mongodb+srv://admin:" + process.env.DBPASS + "@cluster0.xpbd4.mongodb.net/" + process.env.DBNAME + "?retryWrites=true&w=majority", {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.set("useCreateIndex", true);
app.use(cors({origin: "http://localhost:3000", credentials: true}));
app.use(bodyParser.urlencoded({
extended: true
}));
app.enable('trust proxy'); // add this line
app.use(session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection })
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(User.createStrategy());
passport.serializeUser(function(user, done) {
console.log("serializing user")
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log("deserializeUser called: " + id)
User.findById(id, function(err, user) {
done(err, user, function(){
console.log("deserializeUserError: " + err)
});
});
});
登录路径
app.post("/login", function(req, res) {
const user = new User({
email: req.body.email,
password: req.body.password
});
req.login(user, function(err) {
console.log("req.login called")
if (err) {
console.log(err)
res.send("Nuts! An unknown error occured")
} else {
passport.authenticate("local")(req, res, function() {
res.send("success")
});
}
});
});
告诉用户他们是否经过身份验证的路由。当服务器在 Heroku 上时返回 false,但在本地运行时返回 true。
app.get("/user/auth", function(req, res){
console.log("auth called");
if (req.isAuthenticated()) {
res.send("true")
} else {
res.send("false")
}
})
我登录用户的前端React App
function submit(event){
event.preventDefault();
axios({
method: 'post',
data: Querystring.stringify(user),
withCredentials: true,
url: props.serverURL + '/login',
headers: {
'Content-type': 'application/x-www-form-urlencoded'
}
}).then(res => {
console.log("resdata: " + res.data)
if (res.data === "success"){
props.reAuth();
props.history.push('/');
}else{
setResult((prevValue) => {
return (
res.data.toString()
)
});
}
}).catch(function(err){
setResult((prevValue) => {
return (
"Invalid email or password"
)
});
})
}
最近应用程序中检查身份验证的部分
function reAuth(){
axios.get(serverURL + "/user/auth", {withCredentials: true}).then(res => {
console.log(res.data)
setAuth(res.data)
})
}
解决方案
我遇到了一个问题,我的护照会话无法在 res.redirect 中幸存下来,我发现我在序列化和反序列化函数中缺少一个返回语句,即使我在本地运行它可能对你有用
passport.serializeUser(function(user, done) {
console.log("serializing user")
return done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log("deserializeUser called: " + id)
User.findById(id, function(err, user) {
return done(err, user, function(){
console.log("deserializeUserError: " + err)
});
});
});
推荐阅读
- python - 使用 Python 访问第二张 WIFI 卡
- javascript - 如何在使用 React Native 中的 Hooks 更新状态后立即执行函数?
- node.js - 在 Express 路由中检测 Mongoose/MongoDB 错误而不是 Mongoose.connect 回调
- reactjs - 我应该每个组件有一个 useDispatch 吗?
- python - 在熊猫中选择具有已定义列的最小值和最大值的行
- operating-system - 如何在 RISC-V 平台的用户模式应用程序中触发机器调用?
- excel - 计算数组中连续个数(1)的数量
- javascript - Node js 使用数据库中的数据进行渲染
- javascript - 使用 javascript 从 KML/KMZ 文件导入数据
- git - 从 CodeBuild 提交和推送到 GitHub 需要哪些步骤?