Как использовать response-redux для хранения токена и использования его по нескольким запросам?

1

Я создаю приложение, использующее реакцию native, которое требует, чтобы я выполнял несколько get request на получение одного API с токеном.

Скажем, URL-адрес подобен этому

URL-адрес токена = https://test.co/v1/tokens, URL-адрес API 1 = https://test.co/v1/students и URL-адрес API 2 = https://test.co/v1/cars

Прежде всего, чтобы получить данные из URL-адресов API, я написал это следующим образом

Пример для students_actions.js

import axios from 'axios';
import { FETCH_STUDENT } from './types';

const TOKEN_URL = '...'
const STUDENT_URL = '...'

export const fetchStudent = (callback) => async (dispatch) => {
    axios.post(TOKEN_URL, {
        email: 'email',
        password: 'password',
        role: 'user'
    })
    .then((response) => {
        const accessToken = response.data.token;
        //console.log(accessToken);
        axios.get(STUDENT_URL, {
            headers: { 'Authorization': 'Bearer '.concat(accessToken) }
        })
        .then((studentResponse) => {
            dispatch({ type: FETCH_STUDENT, payload: studentResponse.data });
            callback();
        })
        .catch((e) => {
            console.log(e);
        });
    })
    .catch((error) => {
        console.log(error);
    });
};

Пример для students_reducers.js

import { FETCH_STUDENT } from '../actions/types';

const INITIAL_STATE = {
    data: []
};

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case FETCH_STUDENT:
            return action.payload;
        default:
            return state;
    }
}

и вызовите его внутри функции рендеринга, как это

//some code
import { connect } from 'react-redux';

import * as actions from '../actions';

onButtonPressProfile = () => {
    this.props.fetchStudent(() => {
        this.props.navigation.navigate('Profile');
    });
}
class StudentProfile extends Component {
    render() {
        return(
            <View><Text>{this.props.students.name}</Text></View>
        );
    }
}

function mapStateToProps({ students }) {
    return { students: students.data };
}

export default connect(mapStateToProps, actions)(StudentProfile);

Хотя это все работает без каких-либо проблем, я чувствую, что students_actions.js можно упростить, написав код для извлечения токена в другом файле и вызовите значение обратно в students_actions.js для GET request.

Причина в том, что мне не нужно запрашивать токен каждый раз, когда я хочу получить доступ к students или cars. Допустим, я сделал запрос один раз, и я могу использовать тот же токен как 24 часа для доступа к API. По истечении этого срока я должен выполнить еще один запрос на токен, чтобы снова получить доступ к API.

Я уже написал код для token_actions.js вместе с token_reducer.js. Ниже приведены два кода.

token_actions.js

//import library
// this code works
const TOKEN_URL = apiConfig.url + 'tokens';
const auth = {
    email: 'email',
    password: 'password',
    role: 'user'
};

export const fetchToken = () => async (dispatch, getState) => {
        axios.post(TOKEN_URL, auth)
        .then((response) => {

            dispatch({ type: FETCH_TOKEN, payload: response.data.token });
        })
        .catch((error) => {
            console.log(error);
        });
};

token_reducer.js

import {
    FETCH_TOKEN
} from '../actions/types';

const INITIAL_STATE = {
    data: []
};

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case FETCH_TOKEN:
            return action.payload;
        default:
            return state;
}

}

students_actions.js

axios.get(STUDENT_URL, { headers: {
                           'Authorization': 'Bearer '.concat(here is the value from token_actions)}})

И теперь я застрял в том, как мне позвонить/импортировать полезную нагрузку из token_actions.js в students_actions.js? Должен ли я использовать mapStateToProps или есть ли другой способ сделать это?

Сейчас у этого приложения еще нет функции аутентификации. В основном это приложение, которое показывает данные, полученные из API.

Я написал это приложение в основном на основе примеров, которые я нашел в Интернете, и для этого случая я нашел этот пример, но, похоже, не совсем то, чего хочу достичь.

Я не совсем понимаю javascript, поэтому я буду очень рад, если кто-нибудь сможет указать любую ссылку, связанную с этим делом, или, возможно, такие же вопросы здесь, на Stackoverflow, а также, возможно, на некоторые предложения.

Спасибо.

Теги:
react-native
react-redux
redux-thunk

1 ответ

1

Логичным было бы создать нечто вроде AuthReducer, где вы храните маркер и токен обновления. Это пример моего основного AuthReducer:

export const INITIAL_STATE = {
  oAuthToken: '',
  refreshToken: '',
};

export default AuthReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case REFRESH_OAUTH_DATA:
      const { oAuthToken, refreshToken } = action.payload;
      return { ...state, oAuthToken, refreshToken };

    case LOGOUT:
      return INITIAL_STATE;

    case LOGIN_FETCH_SUCCESS:
      const { oAuthToken, refreshToken } = action.payload;
      return { ...state, oAuthToken, refreshToken };

    default:
      return state;
  }
};

Теперь вы можете получить свой токен в своих действиях, используя метод getState, который делает что-то вроде:

export const fetchStudent = (callback) => async (dispatch, getState) => {
    const token = getState().AuthReducer.oAuthToken;
    ....
};

Помните, что если вы используете ES6, вы также можете использовать ожидание:

export const fetchStudent = (callback) => async (dispatch, getState) => {
    try {
        const accessToken = getState.AuthReducer.oAuthToken;

        let response = await axios.get(STUDENT_URL, {
            headers: { 'Authorization': 'Bearer '.concat(accessToken) }
         })

         dispatch({ type: FETCH_STUDENT, payload: studentResponse.data });
         callback();
    } catch(e) {
        console.log(e);
    }
};

Таким образом, ваш код легче читать и поддерживать.

  • 0
    Как мне импортировать AuthReducer ? Это как import { AuthReducer } from './AuthReducer'; на вершине students_actions.js ?
  • 0
    Нет, метод getState - это метод из вашего избыточного хранилища, который доступен в вашем действии благодаря redux-thunk. Вам не нужно импортировать редуктор в вашем действии, чтобы получить к нему доступ.
Показать ещё 6 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню