javascript - 如何使用 react-redux 存储 token 并在多个 axios 请求上使用它?

标签 javascript api react-native react-redux redux-thunk

我正在使用 React Native 构建一个应用程序,它要求我使用 token 在同一个 API 上执行多个 get 请求

假设 url 是这样的

token URL = https://test.co/v1/tokens,API URL 1 = https://test.co/v1/students 和 API URL 2 = https://test.co/v1/cars

首先,为了从任一 API URL 获取数据,我是这样写的

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 可以通过编写代码来进一步简化,以在其他文件中检索 token 并在 students_actions 中调用该值。 js 用于 GET 请求

原因是我不必每次访问studentscars 时都请求 token 。比方说,我确实请求过一次,我可以在大约 24 小时内使用相同的 token 来访问 API。一旦它过期,我就必须再次请求 token 以再次访问 API。

我已经为 token_actions.jstoken_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 获取的数据的应用程序。

我主要根据我在网上找到的示例编写了这个应用程序,对于这种情况,我找到了这个 example但似乎并不是我真正想要实现的目标。

我不太了解 javascript,所以如果有人能指出与此案例相关的任何链接或 Stackoverflow 上的相同问题以及一些建议,我将非常高兴。

谢谢。

最佳答案

我合乎逻辑的做法是创建类似 AuthReducer 的东西,您可以在其中存储 token 和刷新 token 。这是我的基本 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 方法在您的操作中获取您的 token :

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

请记住,如果您使用的是 ES6,您可能还想使用 await:

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: response.data });
         callback();
    } catch(e) {
        console.log(e);
    }
};

这样您的代码就更易于阅读和维护。

关于javascript - 如何使用 react-redux 存储 token 并在多个 axios 请求上使用它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47302699/

相关文章:

javascript - 如何在不调整 reactjs 背景图像大小的情况下进行缩放

ruby-on-rails - 给定特定的纬度/经度,如何计算出与纽约市附近地铁入口的距离?

Azure API 管理 - 未强制执行订阅 key

python - 在 model.py 中的函数内进行 API 调用是否可以,为什么我的应用程序在执行此操作后速度减慢这么多?

reactjs - react native "Value for longitude cannot be cast from String to Double"

reactjs - 有没有类似 bootstrap for web 的 React-Native 风格框架?

javascript - 无法在 Protractor 中运行三个文件?

php - JQuery 验证错误或用户错误?

javascript - Drupal.t 没有出现在翻译中

javascript - 无法在 native react 中调用函数