проблема с добавлением аторизации в заголовки с использованием jwt authoriation react js?

#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),
    ]);
 

почему просто работает здесь, а не внутри моей функции?