#react-native #authentication #apollo-client
Вопрос:
Я начинаю с Аполлона. У меня возникли проблемы с обновлением токена после входа в систему. Он всегда получает предыдущий токен, который был сохранен в AsyncStorage. И когда я перехожу на домашнюю страницу (после входа в систему), при выполнении запроса возвращаю ошибку аутентификации. Я использую Apollo с реактивным и машинописным текстом. Ниже приведен код моего приложения, Логин и консоль.вход: Заранее спасибо!
Приложение.tsx
import { registerRootComponent } from 'expo'
import AsyncStorage from '@react-native-async-storage/async-storage'
import { StatusBar } from 'expo-status-bar'
import React from 'react'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import AppLoading from 'expo-app-loading'
import { useFonts } from 'expo-font'
import {
ApolloClient,
ApolloLink,
InMemoryCache,
HttpLink,
concat
} from '@apollo/client'
import { ApolloProvider } from '@apollo/react-hooks'
import { createUploadLink } from 'apollo-upload-client'
import { MainStackNavigator } from '../src/navigation/MainStackNavigator'
function App() {
const isLoadingComplete = (
<AppLoading
startAsync={this._cacheResourcesAsync}
onFinish={() => this.setState({ isReady: true })}
onError={console.warn}
/>
)
const [fontsLoaded] = useFonts({
Poppins: require('../assets/fonts/Poppins.ttf'),
'Poppins-Bold': require('../assets/fonts/Poppins-Bold.ttf')
})
if (!fontsLoaded) {
return <AppLoading />
}
const httpLink = new HttpLink({
uri: 'localhost:4000/graphql'
})
const getToken = async () => {
const token = await AsyncStorage.getItem('token')
return token
}
const token = getToken()
const authMiddleware = new ApolloLink((operation, forward) => {
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
})
console.log('Token from App.tsx >>>>> ', token)
return forward(operation)
})
// createUploadLink()
const client = new ApolloClient({
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
departments: {
merge(existing, incoming) {
return incoming
}
},
outsources: {
merge(existing, incoming) {
return incoming
}
},
users: {
merge(existing, incoming) {
return incoming
}
}
}
}
}
}),
link: concat(authMiddleware, httpLink)
})
if (!isLoadingComplete) {
return null
} else {
return (
<ApolloProvider client={client}>
<SafeAreaProvider>
<MainStackNavigator />
<StatusBar />
</SafeAreaProvider>
</ApolloProvider>
)
}
}
registerRootComponent(App)
Журнал консоли:
Token from App.tsx >>>>> Promise {
"_U": 0,
"_V": 1,
"_W": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImRpZWdvLnJvZHJpZ28uYW5kcmFkZUBnbWFpbC5jb20iLCJzdWIiOiI2MDc1OTBmMTc5ZjQ2ZjAwMjYyMzlkYWIiLCJpYXQiOjE2MTk5Njk1MDksImV4cCI6MTYxOTk3NjcwOX0.qpazBU9gzKgUN2H-o0_hFP4h2gtieLpLyC6dk5DVju0",
"_X": null,
}
=== Token after login ==> eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImRpZWdvLnJvZHJpZ28uYW5kcmFkZUBnbWFpbC5jb20iLCJzdWIiOiI2MDc1OTBmMTc5ZjQ2ZjAwMjYyMzlkYWIiLCJpYXQiOjE2MTk5NzA5NzIsImV4cCI6MTYxOTk3ODE3Mn0.3c3jlMELNkzQplxH_tQVlR_1GbCOdLX0hMKF6NXsAPk
Войдите в систему.tsx
const setToken = async token => {
await AsyncStorage.setItem('token', token)
console.log('=== Token after login ==> ', token)
return token
}
export function Login({ navigation }: Props) {
const [
login,
{ data: loginData, loading: mutationLoading, error: mutationError }
] = useMutation(LOGIN, {
onCompleted: loginData => setToken(loginData.login.token)
})
Ответ №1:
У меня та же проблема. Проверил документацию AsyncStorage. Получить товар возвращает обещание: https://react-native-async-storage.github.io/async-storage/docs/api/
JSON.parse(токен) исправил это и смог получить строку токена.