Авторизация HTTP-заголовка React и Redux

Я пытаюсь настроить аутентификацию React с помощью своего API-интерфейса. Серверная часть API использует адрес электронной почты и пароль, а также создает токен для каждого нового пользователя. Все они предоставляются через прямой JSON, а не через JWT, поэтому я использую Auth0 tut и этот Stack q /a в качестве отправной точки.

Моя первая цель - сделать простой вход и перенаправление. Я подключил действие/редуктор, и теперь я делаю вызовы API. Я использую базовый вызов аутентификации, конвертирую его в 64-битный символ и отправляю через заголовок. Они протестированы и работают через Postman.

Когда я выполняю эту текущую настройку React, в консоли отображается "Выбор", но никогда не "Я здесь", и страница просто перезагружается. Я не уверен, где это исправить и получить авторизацию и перенаправление. Есть идеи, где я ошибаюсь?

HomePage.js (контейнер)

class HomePage extends React.Component {
 constructor(props) {
  super(props);
 }

 render() {
  const { dispatch, isAuthenticated } = this.props;
 return (
   <div>
     < HomeHeader onLogin={this.props.onLogin} />
   </div>
  );
 }
}

 function mapStateToProps(state) {
  return { loginResponse: state.loginResponse };
 }

 function mapDispatchToProps(dispatch) {
 return {
   onLogin: (creds) => dispatch(loginUser(creds)),
 };
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(HomePage);

AuthorizationActions.js (действия)

function requestLogin(creds) {
 return {
  type: types.LOGIN_REQUEST,
  isFetching: true,
  isAuthenticated: false,
  creds
 }
}
function receiveLogin(user) {
 return {
  type: types.LOGIN_SUCCESS,
  isFetching: false,
  isAuthenticated: true,
  id_token: user.id_token
 }
}

export function loginUser(creds) {
 **console.log("Fetching");**
 const hash = new   Buffer(`${creds.username}:${creds.password}`).toString('base64')

return fetch('http://api.xxx.dev/sessions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ${hash}'
  },
 })
  .then(response => {
    **console.log("I'm here");**
    if(response.status >= 200 && response.status < 300){
      console.log("Response; ", response);
      // Dispatch the success action
      dispatch(receiveLogin(user));
      localStorage.setItem('id_token', user.id_token);
    } else {
      const error = new Error(response.statusText);
      error.response = response;
      dispatch(loginError(user.message))
      throw error;
    }
  })
  .catch(error => { console.log('Request Failed: ', error);});
 }

AuthorizationReducer.js (редуктор)

import { browserHistory } from 'react-router';
import Immutable from 'immutable';

const initialState = new Immutable.Map({
 username: '',
 password: '',
 isLoggingIn: false,
 isLoggedIn: false,
 isFetching: false,
 error: null,
 isAuthenticated: localStorage.getItem('id_token') ? true : false
});

function authenticationReducer(state = initialState, action) {
 switch ( action.type ) {
 case 'LOGIN_REQUEST':
  return { ...state,
      isFetching: true,
      isAuthenticated: false,
      user: action.creds
  }
 case 'LOGIN_SUCCESS':
  return {
    ...state,
    browserHistory: browserHistory.push('/dashboard')
  }
 case 'LOGIN_FAILURE':
  return alert('Crap, there are login failures');
 default:
  return state;
 }
}
export default authenticationReducer;

configureStore.js (Магазин)

const middleware = applyMiddleware(
  thunk,
  apiMiddleware,
  global.window ? logger : store => next => action => next( action )
);
const store = createStore( reducers, initialState, compose(middleware,    window.devToolsExtension ? window.devToolsExtension() : f => f  ))

Компонент AuhorizeLogin.js

 constructor(props, context) {
  super(props, context);
  this.state = {};
  this._login = this._login.bind(this);
 }

 _login(e) {
  e.preventDefault;
  const email = this.refs.email;
  const password = this.refs.password;
  const creds = { email: email.value.trim(), password: password.value.trim() };
  this.props.onLoginClick(creds);

}

Компонент HomeHeader.js

 `_handleChange(eventKey) {
< AuthorizeLogin onLoginClick={this.props.onLogin}/>);
`

Контейнер HomePage.js

constructor(props) {
 super(props);
}
render() {
 const { dispatch, isAuthenticated } = this.props;
 return (
 ...
 < HomeHeader onLogin={this.props.onLogin} />
 ...
 )
}

function mapStateToProps(state) {

return {
 loginResponse: state.loginResponse,
 };
}

function mapDispatchToProps(dispatch) {
 return {
  onLogin: (creds) => dispatch(loginUser(creds)),
 };
}

export default connect(
 mapStateToProps,
 mapDispatchToProps
 )(HomePage);

person Rich Everts    schedule 26.08.2016    source источник
comment
Вы упомянули, что страница перезагружается; возможно, вы используете тег form и забыли event.preventDefault()?   -  person Josh David Miller    schedule 26.08.2016
comment
Я добавил его в функцию onClick в компоненте. Мне нужно добавить его в мои действия или где-то в редьюсерах, если они вызывают другое действие?   -  person Rich Everts    schedule 26.08.2016
comment
Можете ли вы показать этот код? Я думаю, что проблема, скорее всего, в вашем компоненте HomeHeader.   -  person Josh David Miller    schedule 27.08.2016
comment
Я обновил код выше. Должна быть запущена dispatch(receiveLogin(user)); в LoginUser, поскольку он получает успех, а затем перенаправляет.   -  person Rich Everts    schedule 27.08.2016
comment
Здесь слишком много кода для поста SO. Я до сих пор не вижу весь ваш код и подозреваю, что большая часть того, что вы опубликовали, даже не имеет отношения к вашей проблеме. А с компонентом HomeHeader я даже не уверен, на что смотрю; некоторые отсутствуют? Попробуйте создать минимальный воспроизводимый сценарий или решить этот вопрос вне SO.   -  person Josh David Miller    schedule 28.08.2016


Ответы (1)


Попробуйте с return fetch('http://api.xxx.dev/sessions'... . Не проверено, но это должно привести вас к «Я здесь». В конце концов, оберните стрелочную функцию {}

person Ormus    schedule 29.08.2016
comment
Пробовал этот. Хороший улов. Теперь получаю эту ошибку: (программа): 1 Uncaught (в обещании) Ошибка: действия должны быть простыми объектами. Используйте специальное ПО промежуточного слоя для асинхронных действий. - person Rich Everts; 29.08.2016
comment
Я предлагаю прочитать об этом в будущем: Асинхронные действия - person Ormus; 29.08.2016