Непонимание проблем, возникающих при обработке ошибок - PullRequest
0 голосов
/ 18 октября 2019

Я узнаю о реакции и джанго. Я установил django-rest-auth для обработки создания учетных записей и аутентификации пользователей. Я также хотел узнать о реакции, и я установил axios , чтобы сделать http запрос к моему django rest api. Я хочу, чтобы у меня была «всплывающая» страница, на которой пользователи сначала заходили бы на сайт. Если пользователь уже вошел в систему, он увидит свой профиль и другой контент. Если пользователь не вошел в систему, ему должна быть предоставлена ​​страница входа.

Вот мой код App.js, который у меня есть.

import React, { useState, useEffect } from 'react';
import axios from 'axios';

import logo from './logo.svg';
import './App.css';

function LoginPage(props) {

    console.log('LoginPage props are:');
    console.log({ props });

    return (<div className="LoginPage">props are: {props}</div>)
}

function SplashPage(props) {
    const [currentUser, setCurrentUser] = useState(null);

    console.log('SplashPage props are:');
    console.log({ props });

    const userUrl = 'http://localhost:8000/rest-auth/user/';
    console.log('userUrl is:' + userUrl);
    axios.get(userUrl)
        .then(res => { setCurrentUser(res.data); })
        .catch((error) => {
            console.log(error.response);
            return (<div><LoginPage /></div>);
        })
    return (<div className="SplashPage">[{userUrl}] [{currentUser}] </div>);

}


function App() {
    return (
    <div>
      <SplashPage />
    </div>
  );
}

export default App;

Вот мой файл index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: 
serviceWorker.unregister();

При переходе на http://localhost:3000 я получаю такой результат:

enter image description here

В консоли разработчика выглядит как

enter image description here

Я надеялся увидеть содержание моей функции LoginPage.

1 Ответ

1 голос
/ 18 октября 2019

[ОБНОВЛЕННЫЙ ОТВЕТ]

Вы возвращаете <div className="SplashPage">[{userUrl}] [{currentUser}] </div> до <div><LoginPage /></div>, потому что он находится вне цепочки axios .then () (то есть он вызывается непосредственно после axios.get () и перед любым кодомв блоках .then () или .catch ()

Должно работать:

  • инициализировать текущего пользователя с помощью loaderState, чтобы избежать мерцания содержимого
  • Обновитьсостояние в пределах axios .then () или .catch ()
  • Используйте состояние, чтобы определить, что возвращать из функции вне обещаний

-

function SplashPage(props) {
    const [currentUser={notLoaded:true}, setCurrentUser] = useState(null);
    const userUrl = 'http://localhost:8000/rest-auth/user/';
    axios.get(userUrl).then(res => { 
        setCurrentUser(res.data); 
    }).catch((error) => {
        console.log(error)
        setCurrentUser(null)
    })

    //user no authorized
    if(!currentUser)
        return <LoginPage />
    //user authorization unknown
    if(currentUser.notLoaded)
        return <div/>

    //we have a user!
    return <div className="SplashPage">{userUrl} {currentUser}</div>

}

[ОРИГИНАЛЬНЫЙ ОТВЕТ]

РЕДАКТИРОВАТЬ: извините, я неправильно понял ваш вопрос, но оставлю свой оригинальный ответ здесь, если кто-то придет искать связанную проблему.

Вы получаете сообщение об ошибке 403 с сообщением:

Учетные данные для аутентификации не предоставлены

Вам необходимо добавить своего рода авторизацию к вашему запросу (обратитесь к вашей конфигурации / документации django-rest-auth, чтобы узнать, как она ожидает авторизацию. от входящего запросаГНС).

Вы можете настроить это для каждого вызова API вручную или настроить с помощью axios.interceptors.request.use (), который вам нужно будет импортировать и вызывать где-то в вашем приложении (например, в вашем приложении). js or index.js)

В следующем примере:

  • использует axios.interceptors
  • добавляет токен авторизации в заголовок авторизации
  • используетстандартный bearer TOKEN
  • использует firebase auth, чтобы продемонстрировать получение токена через async

(ваша фактическая реализация будет зависеть от того, как настроены ваши API и поток авторизации)

addAuthHeader.js:

import axios from 'axios';
import * as firebase from 'firebase/app';

const apiUrl = 'http://localhost:8000/' // '/' if using the preferred http-proxy-middleware

export default addAuthHeader = () => 
    //if firebase auth callback should be asyncasync
    axios.interceptors.request.use(async (config) => {
      if(config.url.startsWith(apiUrl)){
          const token = await firebase.auth().currentUser.getIdToken(true) 
          config.headers.Authorization = `bearer ${token}`;
          return config;
      }
    });

App.js:

addAuthHeader()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...