如何使用 Laravel Sanctum 和 React 修复 401 Unauthorized 错误?

How do I fix the 401 Unauthorized error with Laravel Sanctum and React?

我有以下 set-up:


Laravel

在我的路线中 (routes/api.php) 我添加了两条路线:

Route::post('login', [App\Http\Controllers\LoginController::class, 'login']);
Route::middleware('auth:sanctum')->get('books', [App\Http\Controllers\BookController::class, 'list']);

在我的 config/cors.php 我添加了:

'paths' => ['api/*', 'sanctum/csrf-cookie'],

'allowed_methods' => ['*'],

'allowed_origins' => ['*'],

'allowed_origins_patterns' => [],

'allowed_headers' => ['*'],

'exposed_headers' => [],

'max_age' => 0,

'supports_credentials' => true,

在我的 .env 中添加了以下内容:

SESSION_DOMAIN=.laravel-api.test
SANCTUM_STATEFUL_DOMAINS=app.laravel-api.test:3000

反应

在 React 中我做了一个函数来轻松发送 Axios 请求:

import axios from "axios";

const apiClient = axios.create({
  baseURL: "http://laravel-api.test",
  withCredentials: true,
});

export default apiClient;

然后我为我的登录表单创建了一个提交功能:

const handleSubmit: FormEventHandler = (e) => {
    e.preventDefault();

    apiClient.get("sanctum/csrf-cookie").then((response) => {
      apiClient
        .post("api/login", {
          email: email,
          password: password,
        })
        .then((response) => {
          console.log(response);
        })
        .catch((error) => {
          console.error(error);
        });
    });
  };

问题

但现在的问题是我做了一个按钮来请求图书列表(/api/books)。请求正在发送,但我收到 401 Unauthorized 错误和 {"message":"Unauthenticated."} 响应。

我看了很多论坛,但找不到我的情况,也没有答案。我可以尝试什么?我如何调试 sanctum 并找出我未通过身份验证的原因。

是饼干吗?是主机名吗?

import React from "react";
import apiClient from "../services/api";

interface Book {
  id: string;
  title: string;
}

const Books = () => {
  const [books, setBooks] = React.useState<Book[]>([]);
  
  React.useEffect(() => {
    apiClient
      .get("/api/books")
      .then((response) => {
        setBooks(response.data);
      })
      .catch((error) => console.error(error));
  }, []);

  const bookList = books.map((book) => <li key={book.id}>{book.title}</li>);

  return <ul>{bookList}</ul>;
};

export default Books;

我认为首先你需要设置不同的主机,你的 React 应用应该有主域 laravel-api.test 而没有端口你的后端应该是:api.laravel-api.test

在你的 .env 中你应该有这个:

SESSION_DOMAIN=.laravel-api.test
SANCTUM_STATEFUL_DOMAINS=laravel-api.test

同样在您的后端:/config/cors.php,将 support_credentials 更改为 true :

'supports_credentials' => true,

最后,这是我每次更改 .env 文件时都必须清除的配置缓存。