在React Native中处理刷新令牌

问题描述 投票:5回答:1

我有一个可以正常验证并返回access_tokenrefresh_token的应用程序。我用AsyncStorage存储它们,并用redux保存/获取access_token。这是我正在构建的第一个应用程序,我在为refresh_token的使用方式和位置而苦苦挣扎。

这是组件loginForm.js中的axios调用

axios({
                url: `${base}/oauth/token`,
                method: 'POST',
                data: formData,
                headers: {
                    Accept: 'application/json',
                    'Content-Type': 'multipart/form-data',
                }
            })
            .then(response => {
                setStatus({ succeeded: true });
                // console.log(response.data);
                deviceStorage.saveKey("userToken", response.data.access_token);
                deviceStorage.saveKey("refreshToken", response.data.refresh_token);
                Actions.main();
            })
            .catch(error => {
                if (error.response) {
                    console.log(error);
                }
            });

这是服务deviceStorage.js

import { AsyncStorage } from 'react-native';

const deviceStorage = {
    async saveItem(key, value) {
        try {
            await AsyncStorage.setItem(key, value);
        } catch (error) {
            console.log('AsyncStorage Error: ' + error.message);
        }
    }
};

export default deviceStorage;

这是令牌操作文件

import { AsyncStorage } from 'react-native';
import {
    GET_TOKEN,
    SAVE_TOKEN,
    REMOVE_TOKEN,
    LOADING_TOKEN,
    ERROR_TOKEN
} from '../types';

export const getToken = token => ({
    type: GET_TOKEN,
    token,
});

export const saveToken = token => ({
    type: SAVE_TOKEN,
    token
});

export const removeToken = () => ({
    type: REMOVE_TOKEN,
});

export const loading = bool => ({
    type: LOADING_TOKEN,
    isLoading: bool,
});

export const error = tokenError => ({
    type: ERROR_TOKEN,
    tokenError,
});

export const getUserToken = () => dispatch => 
    AsyncStorage.getItem('userToken')
        .then((data) => {
            dispatch(loading(false));
            dispatch(getToken(data));
        })
        .catch((err) => {
            dispatch(loading(false));
            dispatch(error(err.message || 'ERROR'));
        });

export const saveUserToken = (data) => dispatch =>
    AsyncStorage.setItem('userToken', data)
        .then(() => {
            dispatch(loading(false));
            dispatch(saveToken('token saved'));
        })
        .catch((err) => {
            dispatch(loading(false));
            dispatch(error(err.message || 'ERROR'));
        });

export const removeUserToken = () => dispatch =>
    AsyncStorage.removeItem('userToken')
        .then((data) => {
            dispatch(loading(false));
            dispatch(removeToken(data));
        })
        .catch((err) => {
            dispatch(loading(false));
            dispatch(error(err.message || 'ERROR'));
        });

这是令牌减少器文件

import {
    GET_TOKEN,
    SAVE_TOKEN,
    REMOVE_TOKEN,
    LOADING_TOKEN,
    ERROR_TOKEN
} from '../actions/types';

const INITIAL_STATE = {
    token: {},
    loading: true,
    error: null
};

export default (state = INITIAL_STATE, action) => {
    switch (action.type) {
        case GET_TOKEN:
            return {
                ...state,
                token: action.token
            };
        case SAVE_TOKEN:
            return {
                ...state,
                token: action.token
            };
        case REMOVE_TOKEN:
            return {
                ...state,
                token: action.token
            };
        case LOADING_TOKEN:
            return {
                ...state,
                loading: action.isLoading
            };
        case ERROR_TOKEN:
            return {
                ...state,
                error: action.error
            };
        default:
            return state;
    }
};

这是认证文件

import React from 'react';
import {
    StatusBar,
    StyleSheet,
    View,
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { Spinner } from '../common';
import { getUserToken } from '../../actions';

class AuthLoadingScreen extends React.Component {

    componentDidMount() {
        this.bootstrapAsync();
    }

    bootstrapAsync = () => {
        this.props.getUserToken().then(() => {
            if (this.props.token.token !== null) {
                Actions.main();
            } else {
                Actions.auth();
            }
        })
            .catch(error => {
                this.setState({ error });
            });
    };

    render() {
        return (
            <View style={styles.container}>
                <Spinner />
                <StatusBar barStyle="default" />
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    },
});

const mapStateToProps = state => ({
    token: state.token,
});


const mapDispatchToProps = dispatch => ({
    getUserToken: () => dispatch(getUserToken()),
});

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

我相信我需要创建一个动作和减速器来获取refresh_token(是正确的吗?),但我不知道该如何处理以及在何处调用它(也许在身份验证文件中?)。对于与此代码示例相关的代码方面的任何帮助,将不胜感激。谢谢

我有一个可以正常验证并返回access_token和refresh_token的应用。我将它们存储在AsyncStorage中,并使用redux保存/获取access_token。这是我正在构建的第一个应用程序...

react-native redux axios refresh-token
1个回答
0
投票

以下步骤

© www.soinside.com 2019 - 2024. All rights reserved.