#reactjs #authentication #react-redux #jwt
#reactjs #аутентификация #react-redux #jwt
Вопрос:
я пытаюсь выполнить авторизацию с помощью токена на предъявителя с моего интерфейса в мой api, в моем api все работает, я тестирую все с помощью insmonia, проблема возникает, когда я пытаюсь добавить авторизацию в заголовки таким образом, я использую react-redux для хранилища so и redux-сохраняется для сохранения сохраняемых данных, и когда я пытаюсь добавить это
export function setToken({ payload }) {
if (!payload) return;
const { token } = payload.auth;
if (token) {
api.defaults.headers.authorization = `Bearer ${token}`;
}
}
export default all([
takeLatest('@auth/persist/REHYDRATE', setToken),
takeLatest('@auth/SIGN_IN_REQUEST', signIn),
takeLatest('@auth/SIGN_UP_REQUEST', signUp),
]);
но когда я перезагружаю свою страницу администратора, где я делаю свои httprequests (post / get и т. Д.) В браузере, он не получает авторизацию в заголовках и говорит
createError.js:16 Uncaught (в обещании) Ошибка: ошибка запроса с кодом состояния 401
Request URL: http://localhost:3333/notifications
Request Method: GET
Status Code: 401 Unauthorized
Remote Address: [::1]:3333
Referrer Policy: strict-origin-when-cross-origin
RESPONSE HEADERS
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 23
Content-Type: application/json; charset=utf-8
Date: Mon, 11 Jan 2021 00:52:14 GMT
ETag: W/"17-IQ4NhR9c983ggGeU6wL1lrE99jM"
Keep-Alive: timeout=5
X-Powered-By: Express
REQUEST HEADERS
Accept: application/json, text/plain, */
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Host: localhost:3333
Origin: http://localhost:3000
Pragma: no-cache
Referer: http://localhost:3000/
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-GPC: 1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Mobile Safari/537.36
что я делаю не так? как я могу добавить авторизацию с предъявителем и токеном?
ВОТ МОЙ РЕПОЗИТОРИЙ ПРОЕКТА, ЕСЛИ ПОМОГАЕТ ПОНЯТЬ ПРОБЛЕМУ https://github.com/dariocoroneldev/Error
Комментарии:
1. я пытаюсь импортировать axios и сделать это таким образом. axios.defaults.headers.common. Авторизация =
Bearer ${token}
; но даже так все еще не работает2. Я специально не использовал
redux-persist
, поэтому не могу сказать, есть ли проблема, связанная с этим, но я предполагаю, что он перезагрузит состояние, но он будет делать это без вызова каких-либо ваших действий, и поэтомуsetToken
никогда не вызывается, и поэтому auth никогда не устанавливается. У меня лично аналогичная настройка, за исключением того, что я беру свой сохраненный токен на верхнем уровне своего приложения и обязательно устанавливаю его при загрузке. Я также отслеживаю, когда установлен auth или нет, и обычно жду его применения, прежде чем выполнять множество любых вызовов API с помощью «useEffects».3. В качестве дополнительного замечания из личного опыта я также использую redux-thunk для своих вызовов API, и я могу легко получить доступ к состоянию и вставить заголовок во все
fetch
вызовы, не передавая его в действие. У меня также есть переменная состояния для каждого вызова API, поэтому я могу легко отслеживать, что загружается или завершено или имеет какую-то ошибку и т.д.4. большое спасибо за совет, я собираюсь исследовать redux-thunk, я никогда об этом не слышал, может, мне поможет спасибо
5. redux-thunk не будет самостоятельным решением этого вопроса, но, по моему опыту, может упростить жизнь, особенно для вызовов auth и API.
Ответ №1:
Когда я добавляю авторизацию в заголовки вне моей функции setToken() в любом месте приложения, тогда это работает, но если я делаю это, я делаю это вручную только для теста, потому что я не знаю, как получить свой токен вне setToken ()
const tokentest =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiaWF0IjoxNjEwMzE3NDcwLCJleHAiOjE2OTY2MzEwNzB9.TikP-RQknI5YMVZmirTH69agd2P0zsW5jIHFcK27kO8';
api.defaults.headers.Authorization = `Bearer ${tokentest}`;
теперь проблема не в том, чтобы отправить авторизацию, теперь я не знаю, как получить свой токен вне функции setToken, используя действия, которые я сгенерировал с помощью библиотеки react-perssit, так что вот мой код
import { takeLatest, call, put, all } from 'redux-saga/effects';
import { toast } from 'react-toastify';
import history from '~/services/history';
import api from '~/services/api';
import { signInSuccess, signFailure } from './actions';
// const test = api.defaults.headers.Authorization;
// console.log(test);
//here it work, but how can i get my token from here?
//why just working here and not inside my fucntion?
const tokentest =
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiaWF0IjoxNjEwMzE3NDcwLCJleHAiOjE2OTY2MzEwNzB9.TikP-RQknI5YMVZmirTH69agd2P0zsW5jIHFcK27kO8';
api.defaults.headers.Authorization = `Bearer ${tokentest}`;
export function* signIn({ payload }) {
try {
const { email, password } = payload;
const response = yield call(api.post, 'session', {
email,
password,
});
const { token, user } = response.data;
if (!user.provider) {
toast.error('usario no es porveedor');
}
//but here doe'snt work nothing when i do this
api.defaults.headers.Authorization = `Bearer ${token}`;
yield put(signInSuccess(token, user));
history.push('/admin');
} catch (err) {
toast.error('error de autenticacion, verifique sus datos');
yield put(signFailure());
}
}
export function* signUp({ payload }) {
try {
const { name, email, password, whatsapp, repeatPassword } = payload;
yield call(api.post, 'users', {
name,
email,
password,
whatsapp,
repeatPassword,
provider: true,
});
history.push('/sesion');
} catch (err) {
toast.error('error al registarse');
yield put(signFailure());
}
}
//here not working too
export function setToken({ payload }) {
if (!payload) return;
const { token } = payload.auth;
console.log(token);
if (token) {
api.defaults.headers.Authorization = `Bearer ${token}`;
}
}
export default all([
takeLatest('@auth/persist/REHYDRATE', setToken),
takeLatest('@auth/SIGN_IN_REQUEST', signIn),
takeLatest('@auth/SIGN_UP_REQUEST', signUp),
]);
почему просто работает здесь, а не внутри моей функции?