使用AsyncStorage全局存储令牌

时间:2018-11-16 21:30:12

标签: javascript react-native async-await

一个星期以来,我一直在学习本机语言,对某些事情感到困惑。

这里是东西: 我正在开发一个解析Imgur API的应用程序,以某种方式通过Webview进行管理以对自己进行身份验证,并获取我本地存储在Webview组件中的accessToken,refreshToken等。

现在,我想将此令牌全局存储在应用程序中,因此我进行了一些研究,发现了有关AsyncStorage的信息(显然不安全地存储令牌,但可以使用它只是一个应用程序)。

这就是我的理解:

  • 您通过setItem提供了一个键和一个值,他们以某种方式将其包装在Promise中(我需要对此做一些研究)
  • 然后您可以在另一个异步函数中将其取回。

这就是我在登录组件中设置项目的步骤:

// login.js

    import React from 'react'
import {AsyncStorage, StyleSheet, WebView} from 'react-native'
import { StackActions, NavigationActions } from 'react-navigation';

const webviewRef = 'webview';
const CLIENT_ID = 'xxxxxxx';

class LoginImgur extends React.Component {
    accessToken : string;
    expiresIn : string;
    refreshToken : string;
    userName : string;

constructor(props) {
    super(props);
}

async storeItem(key, item) {
    try {
        let jsonOfItem = await AsyncStorage.setItem(key, JSON.stringify(item));
        return jsonOfItem;
    } catch (error) {
        console.log(error.message);
    }
}

_resetAction = StackActions.reset({
    index: 0,
    actions: [NavigationActions.navigate({ routeName: 'Index' })],
});

_changeNavigationState = async (webView) => {
   if (this._splitUrl(webView.url) === true) {
       console.log(this.accessToken);
       let json = this.storeItem('ACCESS_TOKEN', this.accessToken);
       this.props.navigation.dispatch(this._resetAction);
   }
};

_splitUrl(url : String) {
    if (url.search("access_token=") > 0) {
        let array = url.split("=");
            this.accessToken =   array[2].split('&')[0];
            this.expiresIn = array[3].split('&')[0];
            this.refreshToken =  array[5].split('&')[0];
            this.userName =  array[6].split('&')[0];
        return (true);
    }
    return (false);
}



webviewProps = {
    style: styles.webview_container,
    ref: webviewRef,
    javaScriptEnabled: true,
    onNavigationStateChange: this._changeNavigationState.bind(this),
    source: {
        uri: 'https://api.imgur.com/oauth2/authorize?client_id=' + CLIENT_ID + '&response_type=token&state=APPLICATION_STATE',
    }
};

render() {
    return (
        <WebView  {...this.webviewProps}/>
    )

}
}


const styles = StyleSheet.create({
    main_container: {
        backgroundColor: 'black'
    },
    webview_container: {
        flex: 1
    }
});

export default LoginImgur

所以现在我进入主屏幕,我想找回此accessToken,以便现在可以进行API调用!!

// Index.js

class Index  extends React.Component {
accessToken : string;

async retrieveItem(key) {
    try {
        const retrievedItem =  await AsyncStorage.getItem(key);
        const item = JSON.parse(retrievedItem);
        return item;
    } catch (error) {
        console.log(error.message);
    }
}

constructor(props) {
    super(props);
}

componentDidMount() {
    this.retrieveItem('ACCESS_TOKEN').then((value) => {
        console.log(value);
        this.accessToken = value;
    }).catch((error) => {
        console.log('Promise is rejected with error: ' + error);
    });
}

_displayAccessToken() {
    console.log(this.accessToken);
}

render() {
    return (
        <View>
            {this._displayAccessToken()}
            <Text>Lol</Text>
        </View>
    )
}

}

但是...根本不起作用。我确实在console.log中获得了令牌,但是并没有保存在我的this.accessToken中。

有人想把它拉出来吗?将会有很大的帮助... enter image description here

1 个答案:

答案 0 :(得分:0)

await AsyncStorage.getItem(key);是异步的:需要一段时间才能获得结果。 render()几乎立即运行,因此当时尚未设置this.accessToken

显示访问令牌的一种方法是将其状态存储在令牌中。当您调用this.setState({ accessToken: value })时,将再次调用render(),因此一旦结果可用,将立即呈现该值。

componentDidMount() {
    this.retrieveItem('ACCESS_TOKEN').then((value) => {
        console.log(value);
        this.setState({accessToken: value }); // cause re-rendering
    }).catch((error) => {
        console.log('Promise is rejected with error: ' + error);
    });
}

render() {
    return (
        <View>
            <Text>{this.state.accessToken}</Text>
            <Text>Lol</Text>
        </View>
    )
}