使用 Axios 通过 laravel/sanctum 验证我的 ReactJS SPA

med*_*ies 1 laravel reactjs axios laravel-sanctum

成功进行身份验证(登录+令牌)后,我仍然无法请求auth:sanctum路由,并且收到以下响应:

在此输入图像描述


登录表单组件

import React, { useState } from "react";

const LoginForm = () => {
    const [email, setEmail] = useState("");
    const [password, setPassword] = useState("");

    const loginHandler = (ev) => {
        ev.preventDefault();

        if (email.length > 0 && password.length > 0) {
            axios.get("/sanctum/csrf-cookie").then(() => {
                axios
                    .post("api/login", {
                        email: email,
                        password: password,
                    })
                    .then((response) => {
                        console.log(response.data);

                    })
                    .catch(function (error) {
                        console.error(error);
                    });
            });
        }
    };
Run Code Online (Sandbox Code Playgroud)

登录操作

    public function login(Request $request)
    {
        $request->validate(['email' => 'required', 'password' => 'required|string']);

        $user = User::where('email', $request->email)->first();

        if (!$user || !password_verify($request->password, $user->password)) {
            return response(['message' => 'Bad credentials'], 401);
        }

        $token = $user->createToken('token')->plainTextToken;

        return response(['user' => $user, 'token' => $token], 201);
    }
Run Code Online (Sandbox Code Playgroud)

登录响应

{
    "user": {
        "id": 7,
        "email": "daphne19@example.com",
        "email_verified_at": "2022-03-09T16:40:59.000000Z",
        "created_at": "2022-03-09T16:40:59.000000Z",
        "updated_at": "2022-03-09T16:40:59.000000Z"
    },
    "token": "5|oCnoaVBBYARcFXwdd7dXegchFLS6fckDgr2Bl0L0"
}
Run Code Online (Sandbox Code Playgroud)

小智 5

解决方案

您需要在 Axios 标头中传递 Sanctum Token。

例子

  1. 您需要在 中设置用户响应LocalStorage
const LoginForm = () => {
const [email, setEmail] = useState("")
const [password, setPassword] = useState("")

const loginHandler = (ev) => {
    ev.preventDefault()

    if (email.length > 0 && password.length > 0) {
        axios.get("/sanctum/csrf-cookie").then(() => {
            axios
                .post("/api/login", {
                    email: email,
                    password: password,
                })
                .then((response) => {
                     // Set response in LocalStorage
                     localStorage.setItem('user', JSON.stringify(response.data))
                })
                .catch(function (error) {
                    console.error(error)
                })
        })
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 您需要在 Axios 标头中传递令牌
// Find user
const user = JSON.parse(localStorage.getItem('user'));
// Define Header
const headers = {
    accept: 'application/json',
    Authorization: 'Bearer ' + user.token
}

// Set token in Axios Header
axios
    .get("/api/your-uri-here", {
        headers: headers
    })
    .then((res) => { /* ... */ })
    .catch((err) => { /* ... */ })
Run Code Online (Sandbox Code Playgroud)

  • 授权: '**B**earer ' <= 使用大写字母,否则不起作用 (4认同)