我能够使用我的用户名和密码(硬编码)登录,但是,在登录后,我想从API中获取一些数据,只有在经过身份验证的情况下才能完成。因此,问题是如何保持用户登录?
我在反应中不太好,因此任何帮助都将不胜感激!
这是我的代码:
import React, { Component } from 'react';
import { Text, View, StyleSheet,AsyncStorage, FlatList, AppRegistry } from 'react-native';
import { ListItem } from 'react-native-elements';
export default class BMPServer extends React.Component {
constructor(props) {
super(props);
this.state = {
username: 'testuser',
password: 'mypasswordhere',
signedIn: false,
checkedSignIn: false
};
this.getAllDocuments();
}
getAllDocuments = () => {
fetch('https://example.dk/rest/Login/Authenticate/?businessId=1&solutionId=1', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username : this.state.username,
password : this.state.password,
})
})
.then((response) => response.json())
.then((responseDocs) => {
console.log("YOU HAVE SUCCSFULLY LOGGED IN:", responseDocs)
});}
假设您在成功身份验证上获得令牌。
import { AsyncStorage } from 'react-native';
fetch('https://example.dk/rest/Login/Authenticate/?businessId=1&solutionId=1', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username : this.state.username,
password : this.state.password,
})
})
.then((response) => AsyncStorage.setItem(LOGIN_TOKEN, response))
.then((responseDocs) => {
console.log("YOU HAVE SUCCSFULLY LOGGED IN:", responseDocs)
});}
所以,现在您已经存储在Asyncstorage上了。因此,例如,在您的初始屏幕上,Splash屏幕给出一个条件,以检查是否使用
显示令牌AsyncStorage.getItem(LOGIN_TOKEN);
React Navigation在https://reactnavigation.org/docs/en/auth-flow.html
上有一个带有其开关导航器的身份验证示例基本上,您有一个特殊的导航器,可以在记录和未记录的用户之间切换,因为异步持续存在,应该没有问题。
这是代码,运行它。这很简单:)
import React from 'react';
import {
ActivityIndicator,
AsyncStorage,
Button,
StatusBar,
StyleSheet,
View,
} from 'react-native';
import { createStackNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';
class SignInScreen extends React.Component {
static navigationOptions = {
title: 'Please sign in',
};
render() {
return (
<View style={styles.container}>
<Button title="Sign in!" onPress={this._signInAsync} />
</View>
);
}
_signInAsync = async () => {
await AsyncStorage.setItem('userToken', 'abc');
this.props.navigation.navigate('App');
};
}
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome to the app!',
};
render() {
return (
<View style={styles.container}>
<Button title="Show me more of the app" onPress={this._showMoreApp} />
<Button title="Actually, sign me out :)" onPress={this._signOutAsync} />
</View>
);
}
_showMoreApp = () => {
this.props.navigation.navigate('Other');
};
_signOutAsync = async () => {
await AsyncStorage.clear();
this.props.navigation.navigate('Auth');
};
}
class OtherScreen extends React.Component {
static navigationOptions = {
title: 'Lots of features here',
};
render() {
return (
<View style={styles.container}>
<Button title="I'm done, sign me out" onPress={this._signOutAsync} />
<StatusBar barStyle="default" />
</View>
);
}
_signOutAsync = async () => {
await AsyncStorage.clear();
this.props.navigation.navigate('Auth');
};
}
class AuthLoadingScreen extends React.Component {
constructor() {
super();
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const userToken = await AsyncStorage.getItem('userToken');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
));
我已经找到了解决我问题的解决方案。 fetch()自动设置cookie,但在获取时必须包括此cookie:凭据:'include'inclage'。不需要异步或类似的东西,这只是浪费时间,不幸的是,即使经过一周的搜索此问题,我也无法在互联网上的任何地方找到解决方案,显然该解决方案非常非常非常简单。
请参阅下面的代码以获取详细信息:
getAllDocuments = () => {
fetch('LOGIN_URL_HERE', { //*HERE I AM AUTHENTICATING*
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'Connection': 'Keep-Alive',
},
body: JSON.stringify({
username: 'myemail',
password: 'mypassword'
})
})
.then((response) => response.json())
.then((res) => {
console.log("This is the user:", res)
fetch('DOCUMENTS_URL_HERE', { //*HERE I AM FETCHING DOCUMENTS AFTER I HAVE SUCCESSFULLY AUTHENTICATED*
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
credentials: 'include', //USE THIS TO SET COOKIES
body: JSON.stringify({
lastServerSyncDateAsLong: 0,
inserted: {},
edited: {},
deleted: {}
})
})
.then((res) => res.json())
.then((ressDocs) => {
console.log("THESE ARE ALL DOCUMENTS FETCHED FROM API:", ressDocs)
})
})
}