reactjs - Laravel 7 Sanctum : Same domain (*. herokuapp.com)但单独的 React SPA 获取 CSRF token 不匹配

标签 reactjs laravel laravel-7 csrf-token laravel-sanctum

我从这个论坛上读了很多书,也看了很多关于如何使用 Sanctum Auth 将单独的 React/Vue SPA 连接到 Laravel API 的教程视频,但没有一个解决方案适合我。这是我的学校项目。

这就是我到目前为止所做的。

我创建了 2 个文件夹,一个用于 api,一个用于前端。我在 api 文件夹中安装了 Laravel,并在 frontend 文件夹中安装了 React 应用程序。这两个都是 Git 初始化的,并且有自己的 Github 存储库。此外,它们都部署到 Heroku。

API

Repository: https://github.com/luchmewep/jarcalc_api

Website: https://jarcalc-api.herokuapp.com

前端

Repository: https://github.com/luchmewep/jarcalc_front

Website: https://jarcalculator.herokuapp.com

在本地,一切运行良好。我可以将错误消息设置到前端的电子邮件和密码字段,这意味着我已经收到并发送了 laravel_sessionXSRF_TOKEN cookie。我还在虚拟仪表板上显示了经过身份验证的用户的信息,因此在本地一切正常

在互联网上,我的两个应用程序都在运行但不会相互通信。在官方文档中,它们必须至少位于同一域,在这种情况下,它们是同一域 .herokuapp.com 的子域。

这是每个 Heroku 应用程序的环境变量。

API

SANCTUM_STATEFUL_DOMAINS = jarcalculator.herokuapp.com

(I've tried adding "SESSION_DRIVER=cookie" and "SESSION_DOMAIN=.herokuapp.com" but still not working!)

更新

发现 axios 在尝试对/login 进行 POST 请求时没有携带 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 is included in the Mozilla Foundation’s Public Suffix List. This list is used in recent versions of several browsers, such as Firefox, Chrome and Opera, to limit how broadly a cookie may be scoped. In other words, in browsers that support the functionality, applications in the herokuapp.com domain are prevented from setting cookies for *.herokuapp.com." https://devcenter.heroku.com/articles/cookies-and-herokuapp-com

本地 Cookie enter image description here

已部署的 Cookie enter image description here

说明:尽管 API 和前端都有 .herokuapp.com,但这并不意味着它们在同一域中。它在上面的 Heroku 文章中有解释。这意味着 *.herokuapp.com 之间的所有请求都被视为跨站点而不是同一站点

解决方案

由于laravel_session cookie是axios自带的,所以剩下的问题就只有xsrf-token cookie了。要解决这个问题,必须购买一个域名,并为每个域名设置子域名。就我而言,我的 React 前端现在位于 www.jarcalculator.me。而我的 Laravel 后端现在位于 api.jarcalculator.me .由于它们现在无论部署在何处都位于同一站点(React 移至 Github 页面,而 Laravel 移至 Heroku),因此可以自动设置 cookie。

最佳答案

终于通过 Github Student Pack 申请了我的免费域名解决了我的问题。我将我的 React 应用程序的域名设置为 www.jarcalculator.me,同时将我的 Laravel 应用程序的域名设置为 api.jarcalculator.me。由于它们现在是同一域(即 jarcalculator.me)的子域,因此包含 CSRF token 和 laravel_session token 的 cookie 的传递是自动。无需修改 axios 设置。只需将 axios 的 withCredentials 设置为 true 即可。

关于reactjs - Laravel 7 Sanctum : Same domain (*. herokuapp.com)但单独的 React SPA 获取 CSRF token 不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61961955/

相关文章:

php - 如何同时运行两个不同版本的 laravel 和不同的 php 版本

laravel - 如何删除超过一小时的公共(public)存储文件?

reactjs - 如何在 React Highchart 工具提示中添加按钮?

php - 在 1 个有 2 行的字段中仅选择 1 行

php - Laravel - 使用 bundle 从数据库中检索数据

php - 在 laravel 中播种时出现质量分配错误

javascript - 如何防止第二次输入相同的字符

javascript - 动态添加输入字段并跟踪输入的内容

reactjs - 当 redux 存储的非相关部分在 react-redux 中更新时组件重新渲染

php - 获取laravel trans中local的key