Использование токенов для авторизации в Sanctum

avatar
Krystian432345
8 августа 2021 в 20:34
532
1
0

Я хочу использовать 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
    );
}

@Edit

Я не уверен, что хорошо понимаю, но это не работает. Если я попытаюсь получить адрес, который нужно авторизовать, у меня будет статус 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']);
});
Источник

Ответы (1)

avatar
matiaslauriti
8 августа 2021 в 21:42
0

У вас не должно быть необходимости хранить что-либо в каком-либо специальном месте, просто используя конфигурацию Axios следующим образом:

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

withCredentials: true будет хранить токен CSRF и любые учетные данные после входа в систему, поэтому вам больше не придется беспокоиться об отправке любых учетных данных или чем-либо подобном.

Это еще один пример.


Вы также можете воспользоваться преимуществами Axios и также удалить все данные, которые у вас есть, когда запрос возвращает 401 (Неавторизованный) или 419 (Сессия истекла).

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, например vuex, и сначала спрашиваю, является ли текущий пользователь гостем или нет, а затем удаляю все из сеанса с помощью простой выход из системы (на Vue и Laravel).

Это можно сделать с помощью Interceptors.

Krystian432345
9 августа 2021 в 04:40
0

Я не могу проверить это в это время, но я не уверен, что хорошо понимаю. Я должен создать экземпляр axios в отдельном файле и использовать этот экземпляр во всех запросах? Проблема 2: Токен должен быть изменен, потому что Laravel возвращает что-то вроде этого 79|CX1202zNQCpUc2rqp88Bwa48aNQ1F6G5psfk1lLn, но я должен использовать что-то вроде этого Bearer CX1202zNQCpUc2rqp88Bwa48aNQ1F6G5psfk1lLn

matiaslauriti
9 августа 2021 в 04:45
0

1) Да, вы должны вернуть этот экземпляр, созданный Axios (извините, что не ясно). 2) Не должно быть необходимости, должно работать из коробки. Может быть, я путаюсь с файлами cookie, извините в таком случае.

Krystian432345
9 августа 2021 в 20:29
0

Это не работает. Я обновил свой пост, чтобы вы могли проверить мой код.