【问题标题】:Using tokens to authorize in Sanctum在 Sanctum 中使用代币进行授权
【发布时间】:2021-10-12 16:53:38
【问题描述】:

我想将 React 与 Sanctum 一起使用。在 Sanctum 中,我生成了令牌并在登录后将其返回,并且它可以正常工作。但是,登录后,我可以在控制台中看到我的令牌,但是如果我想为已登录的用户打开路由,我必须在标头中发送这个令牌。最好的方法是什么?

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

    if (!Auth::attempt($attr)) {
        return $this->error('Credentials not match', 401);
    }

    return response()->json([
       'access_token' => auth()->user()->createToken('auth_token')->plainTextToken,
       'token_type' => 'Bearer',
    ]);
}

然后登录到 React。

function Login () {
    const emailRef = useRef(),
          passwordRef = useRef();

    const handleSubmit = (event) => {
        event.preventDefault();

        axios.post('http://localhost:8000/api/auth/login', { email: emailRef.current.value, password: passwordRef.current.value })
            .then(res => {
                console.log(res);
            }).catch((error) => {
                console.log(error)
            });
    }
    return(
       // Here is my form
    );
}

@编辑

我不确定我是否理解,但它不起作用。如果我尝试获取地址女巫需要进行自动化,我的状态为 401。 我做实例 instance.php

import axios from 'axios'
let instance = axios.create({
    baseURL: 'http://localhost:8000',
    headers: {
        common: {
            'X-Requested-With': 'XMLHttpRequest',
        }
    },
    withCredentials: true,
});

export default instance;

我登录用户。在 React 中看起来像这样

instance.post('/api/auth/login', {

        email: emailRef.current.value,
        password: passwordRef.current.value
    
}).then(res => {
    console.log(res);
})

通常它可以工作。我想添加一些需要授权的东西。

instance.get('/api/me')
    .then(res => {
        console.log(res.data.data.token);
    }).catch((error) => {
        console.log(error)
    });

在 Api.php 中看起来像这样

Route::post('/auth/register', [AuthController::class, 'register']);

Route::post('/auth/login', [AuthController::class, 'login']);

Route::group(['middleware' => ['auth:sanctum']], function () {
    Route::get('/me', function() {
        echo "Hello World";
    })->name('me');

    Route::post('/auth/logout', [AuthController::class, 'logout']);
});

【问题讨论】:

    标签: javascript reactjs laravel laravel-sanctum


    【解决方案1】:

    您应该不需要在任何特殊的地方存储任何东西,只需使用这样的 Axios 配置:

    axios.create({
        headers: {
            common: {
                'X-Requested-With': 'XMLHttpRequest',
            },
        },
        withCredentials: true,
    });
    

    withCredentials: true 将在您登录后存储CSRF 令牌和任何凭据,因此您不必再担心发送任何凭据或类似的东西。

    This 是另一个例子。


    当请求返回401(未授权)或419(会话已过期)时,您还可以利用 Axios 并删除您存储的所有数据。

    authClient.interceptors.response.use(
        (response) => response,
        (error) => {
            if (error.response &&
                [401, 419].includes(error.response.status) &&
                store.getters[`user/${IS_GUEST_GETTER}`]
            ) {
                store.dispatch(`user/${LOGOUT_ACTION}`);
            }
    
            return Promise.reject(error);
        }
    );
    

    在这个例子中,我使用像 这样的 store,我首先询问当前用户是否是访客,然后通过简单的注销从会话中删除所有内容(在 Vue 和 Laravel 上)。

    您可以使用Interceptors 来做到这一点。

    【讨论】:

    • 这次我不能检查这个,但我不确定我是否理解。我必须在单独的文件中创建 axios 实例并在所有请求中使用此实例吗?问题 2:令牌必须更改,因为 Laravel 返回类似 79|CX1202zNQCpUc2rqp88Bwa48aNQ1F6G5psfk1lLn 但我必须使用类似 Bearer CX1202zNQCpUc2rqp88Bwa48aNQ1F6G5psfk1lLn
    • 1) 是的,您必须返回 Axios 创建的实例(抱歉没有说清楚)。 2)应该没有必要,它应该开箱即用。也许我对 cookie 感到困惑,在这种情况下很抱歉。
    • 它不起作用。我更新了我的帖子,所以你可以检查我的代码。
    猜你喜欢
    • 2023-03-21
    • 2020-07-04
    • 2020-08-08
    • 2021-06-09
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-23
    相关资源
    最近更新 更多