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

Authenticate my ReactJS SPA with laravel/sanctum using Axios

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

Docs

... This token should then be passed in an X-XSRF-TOKEN header on subsequent requests, which some HTTP client libraries like Axios and the Angular HttpClient will do automatically for you.



代码


LoginForm 组件

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);
                    });
            });
        }
    };
    return (
        <form onSubmit={loginHandler}>
            <input
                type="email" value={email}
                onChange={(ev) => {
                    setEmail(ev.target.value.toLocaleLowerCase());
                }}
            />
            <input
                type="password" autoComplete="" value={password}
                onChange={(ev) => {
                    setPassword(ev.target.value);
                }}
            />

            <button> Connect </button>
        </form>
    );
};
export default LoginForm;

登录操作

    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);
    }

登录响应

{
    "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"
}

您需要在Axios Header中传递Sanctum Token。

    first you need to set user response in local storage.
    
        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 local storage
                                 localStorage.setItem('user', JSON.stringify(response.data))
                            })
                            .catch(function (error) {
                                console.error(error);
                            });
                    });
                }
            };

那么需要在axios Header中传递token

   const user = JSON.parse(localStorage.getItem('user'));
   const headers = {
        accept: 'application/json',
        Authorization: 'bearer ' + user.token
    }

   //set token in axios header
   axios.get(API, {
       headers: headers
   })
    .then((res) => { })
    .catch((err) => { })

请在使用 Axios 进行身份验证请求时将 bearer 更改为 Bearer。