我从这个论坛阅读了很多内容,并观看了很多关于如何使用 Sanctum Auth 将单独的 React/Vue SPA 连接到 Laravel API的教程视频,但没有一个解决方案对我有用。这是我的学校项目。
所以这就是我到目前为止所做的。
我创建了 2 个文件夹,一个用于 api,一个用于前端。我在 api 文件夹中安装了 Laravel,并在前端文件夹中安装了 React 应用程序。这两个都是 Git 初始化的,并且有自己的 Github 存储库。此外,它们都部署到 Heroku。
API
存储库:
https://github.com/luchmewep/jarcalc_api
网站:
https://jarcalc-api.herokuapp.com
前端
存储库:
https://github.com/luchmewep/jarcalc_front
网站:
https://jarcalculator.herokuapp.com
在本地,一切运行良好。我可以在前端的电子邮件和密码字段中设置错误消息,这意味着我已经收到并发送了laravel_session和XSRF_TOKEN cookie。我还在一个虚拟仪表板上显示了经过身份验证的用户信息,因此在本地一切正常。
在互联网上,我的两个应用程序都运行但不会相互通信。在官方文档中,它们必须至少在同一个域中,在这种情况下,它们是同一个域的子域,即.herokuapp.com。
这是我为每个 Heroku 应用程序设置的环境变量。
API
SANCTUM_STATEFUL_DOMAINS = jarcalculator.herokuapp.com
(我尝试添加“SESSION_DRIVER=cookie”和“SESSION_DOMAIN=.herokuapp.com”但仍然无法正常工作!)
更新
发现 axios 在尝试 POST /login 请求时没有携带 XSRF-TOKEN。它会自动进行本地测试。
以下是相关代码:
api.tsx
import axios from "axios";
export default axios.create({
baseURL: `${process.env.REACT_APP_API_URL}`,
withCredentials: true,
});
登录.tsx
...
const handleSubmit = (e: any) => {
e.preventDefault();
let login = { email: email.value, password: password.value };
api.get("/sanctum/csrf-cookie").then((res) => {
api.post("/login", login).then((res) => {
/**
* goes here if login succeeds...
*/
console.log("Login Success");
...
})
.catch((e) => {
console.log("Login failed...")
});
})
.catch((e) => {
console.log("CSRF failed...");
});
};
更新
“.herokuapp.com 包含在 Mozilla 基金会的公共后缀列表中。该列表用于多个浏览器的最新版本,例如 Firefox、Chrome 和 Opera,以限制 cookie 的范围。换句话说,在浏览器中支持该功能的应用程序将阻止 herokuapp.com 域中的应用程序为 *.herokuapp.com 设置 cookie。” https://devcenter.heroku.com/articles/cookies-and-herokuapp-com
说明:虽然 API 和前端都有.herokuapp.com,但这并不意味着它们在同一个 domain 上。上面 Heroku 的文章对此进行了解释。这意味着*.herokuapp.com之间的所有请求都被视为跨站点而不是相同站点。
解决方案
由于laravel_session cookie 是由 axios 携带的,剩下的唯一问题就是xsrf-token cookie。要解决这个问题,必须购买一个域名并为每个域名设置子域名。就我而言,我的 React 前端现在位于www.jarcalculator.me而我的 Laravel 后端现在位于api.jarcalculator.me。由于无论部署在哪里,它们现在都是同一个站点(React 移动到 Github 页面,而 Laravel 在 Heroku),cookie 可以自动设置。