如何使用react-redux存储令牌并在多个axios请求中使用它?

时间:2017-11-15 08:34:04

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

我正在使用react native构建一个应用程序,要求我在带有令牌的相同API上执行多个get request

假设网址是这样的

令牌网址= https://test.co/v1/tokens,API网址1 = https://test.co/v1/students,API网址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可以通过编写用于在其他文件中检索令牌的代码来进一步简化,并在students_actions.js内调用值GET request }。

原因是每次我想访问studentscars时,我都不必请求令牌。可以说,我曾经请求了一次,我可以使用相同的令牌24小时来访问API。一旦它过期,我就必须再次请求令牌来再次访问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上有相同的问题,我也会很高兴,也许还有一些建议。

谢谢。

1 个答案:

答案 0 :(得分: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);
    }
};

这样,您的代码便于阅读和维护。