我有一个React应用程序在节点中调用API。js/Express。
前端部署在Netlify(https)中,后端部署在Heroku(https)中。
我的问题是:
说话很便宜,给我看代码......
应用程序。js
require('./configs/passport');
// ...
const app = express();
// trust proxy (https://stackoverflow.com/questions/64958647/express-not-sending-cross-domain-cookies)
app.set("trust proxy", 1);
app.use(
session({
secret: process.env.SESSION_SECRET,
cookie: {
sameSite: process.env.NODE_ENV === "production" ? 'none' : 'lax',
maxAge: 60000000,
secure: process.env.NODE_ENV === "production",
},
resave: true,
saveUninitialized: false,
ttl: 60 * 60 * 24 * 30
})
);
app.use(passport.initialize());
app.use(passport.session());
// ...
app.use(
cors({
credentials: true,
origin: [process.env.FRONTEND_APP_URL]
})
);
//...
app.use('/api', require('./routes/auth-routes'));
app.use('/api', require('./routes/item-routes'));
CRUDendpoint(例如item routes.js):
// Create new item
router.post("/items", (req, res, next) => {
Item.create({
title: req.body.title,
description: req.body.description,
owner: req.user._id // <-- AT THIS POINT, req.user is UNDEFINED
})
.then(
// ...
);
});
用户注册和登录:
class AuthService {
constructor() {
let service = axios.create({
baseURL: process.env.REACT_APP_API_URL,
withCredentials: true
});
this.service = service;
}
signup = (username, password) => {
return this.service.post('/signup', {username, password})
.then(response => response.data)
}
login = (username, password) => {
return this.service.post('/login', {username, password})
.then(response => response.data)
}
//...
}
axios.post(`${process.env.REACT_APP_API_URL}/items`, {
title: this.state.title,
description: this.state.description,
}, {withCredentials:true})
.then( (res) => {
// ...
});
它并没有像预期的那样工作,因为我在Chrome Incognito上进行测试,默认情况下,Chrome会在Incognito模式下阻止第三方cookie(更多详细信息)。
下面是一个列表,其中列出了一些检查您是否存在类似问题的事项;)
如果有帮助,这里有一个清单,列出了您主要需要的不同东西;)
如果要在Heroku上部署,请添加以下行(可以在会话设置之前添加)。
app.set("trust proxy", 1);
特别是,选中选项sameSite
和secure
(此处有更多详细信息)。
以下代码将在生产中设置sameSite:'none'
和secure:true
:
app.use(
session({
secret: process.env.SESSION_SECRET || 'Super Secret (change it)',
resave: true,
saveUninitialized: false,
cookie: {
sameSite: process.env.NODE_ENV === "production" ? 'none' : 'lax', // must be 'none' to enable cross-site delivery
secure: process.env.NODE_ENV === "production", // must be true if sameSite='none'
}
})
);
app.use(
cors({
credentials: true,
origin: [process.env.FRONTEND_APP_URL]
})
);
在Heroku中设置环境变量。例如:
FRONTEND_APP_URL = https://my-project.netlify.app
重要提示:对于CORS URL,请避免在末尾使用斜杠。以下情况可能不起作用:
FRONTEND_APP_URL = https://my-project.netlify.app/ --> avoid this trailing slash!
确保您在API调用中发送凭据(您需要为所有对API的调用发送凭据,包括对用户登录的调用)。
如果您使用axios,您可以使用with凭据
选项。例如:
axios.post(`${process.env.REACT_APP_BACKEND_API_URL}/items`, {
title: this.state.title,
description: this.state.description,
}, {withCredentials:true})
.then( (res) => {
// ...
});
对于测试,您可能希望确保使用每个浏览器提供的默认配置。
例如,截至2021,铬阻止第三方cookie在隐姓埋名模式(但不是在“正常”模式),所以你可能想要有这样的东西:
最后,请记住,每个浏览器对第三方cookie都有不同的政策,总的来说,这些限制预计在未来几年会增加。
例如,预计Chrome将在2023年的某个时候阻止第三方cookie(来源)。
如果您的应用程序需要绕过这些限制,以下是一些选项:
>
实现后端
将您的后端API置于代理之下(如果您使用Netlify,您可以使用_重定向文件轻松设置代理)
问题内容: 我有一个小问题。 如何为多个域设置Cookie? 我确实了解安全性问题,并且我确信以前已经做过。原因是SSO。 即。 将需要将登录域设置为: domain.com,domain1.com,domain2.com。 有没有简单的方法,可以使用PHP和Cookies或其他替代方法? 问题答案: domain.com绝对没有办法为domain1.com设置cookie。您试图做的事情只能通过
我目前正在从事一个托管在域上的laravel项目。此应用程序的一部分(某些功能)必须位于不同的域上。我在我的网上找到了一条路。在php中,我用以下命令映射了所有路由: 以及需要以相同方式位于另一个域上,但具有不同域的路由。好啊在主域中,我创建了一个具有src属性的图像: 指向此方法路线: 它起作用了。我在不同的域上共享同一个会话,但是,我想问你们,对于这个案例场景,你们是否知道更好的方法。我知道这
问题内容: 如何使 connect.sid cookie本身仅是会话cookie,而不是持久性cookie? 我尝试失败 但是cookie仍具有到期时间戳。 问题答案: 以上工作。因此,通过将maxAge设置为null,我确实管理了expressjs以使用会话cookie。ew
问题内容: 我几个月前开始使用PHP。为了为我的网站创建一个登录系统,我阅读了有关cookie和会话及其区别(cookie存储在用户的浏览器中以及服务器上的会话中)的信息。当时,我更喜欢cookie(谁不喜欢cookie ?!),只是说:“谁在乎?我在将它存储在服务器中没有任何好处”,所以,我继续使用cookie我的学士毕业项目。但是,在完成了我的应用程序的大部分工作之后,我听说对于存储用户ID的
问题内容: 我不确定这是否可能。 我的“活动”网站正在处理注册并将其保存到我们的数据库中,但是我们的主站点负责处理信用卡处理。通过在主网站上处理当前的购买,会话可用于将数据传递到付款/抄送屏幕。 不必更改我的付款代码(例如接受$ _GET参数),我的变量是否应该传递过来? 例: 我的页面在上面查找地址会话变量。 问题答案: 跨域会话ID 默认情况下,使用cookie传递会话ID。由于您的网站位于不
问题内容: 当我在本地发出请求时,维护FlexSession完全没有问题。但是,当我从另一台计算机发出请求时,它将为每个请求创建重复的FlexSession。我注意到每个请求的JSESSIONID是不同的,这可能是导致重复会话的原因。 但是我不知道为什么会这样。我得到的具体错误是: 我的crossdomain.xml如下: 编辑: 我们在后端使用spring-flex集成。同样,这会在多个浏览器中