Как обновить токен в клиенте apollo после входа в систему

#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(токен) исправил это и смог получить строку токена.