【问题标题】:How to add header for apollo client in react native application如何在反应原生应用程序中为 apollo 客户端添加标头
【发布时间】:2018-10-14 04:19:31
【问题描述】:

这就是我在我的 react native 应用程序中使用上传链接定义 apollo 客户端的方式。

我想添加一些带有令牌值的标头,它会随每个请求一起发送。但不幸的是,我没有找到 react native 的示例。

import { AsyncStorage } from 'react-native'
import { ApolloClient } from 'apollo-client'
import { createUploadLink } from 'apollo-upload-client'
import { InMemoryCache } from 'apollo-cache-inmemory'

const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql'
  }),
  cache: new InMemoryCache()
})

我想在标题中发送这个值:

const token = await AsyncStorage.getItem('auth.token')

更新

我不知道如何将令牌从 AsyncStorage 插入到标头。 Await 不能在这里工作,因为它没有在异步函数中使用:

const token = await AsyncStorage.getItem('auth.token') // await can't work here

// Initiate apollo client
const client = new ApolloClient({
  link: createUploadLink({
    uri: 'http://localhost:3000/graphql',
    headers: {
      authorization: token
    }
  }),
  cache: new InMemoryCache()
})

// Wrap apollo provider
const withProvider = (Component, client) => {
  return class extends React.Component {
    render () {
      return (
        <ApolloProvider client={client}>
          <Component {...this.props} client={client} />
        </ApolloProvider>
      )
    }
  }
}

export default async () => {
  Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client))

  Navigation.startSingleScreenApp({
    screen: {
      screen: 'MainScreen'
    }
  })
}

【问题讨论】:

    标签: javascript react-native apollo-client


    【解决方案1】:

    createUploadLink 有一个与createHttpLink headers 属性匹配的 headers 属性。

    headers:表示要作为请求头发送的值的对象

    示例

    const token = await AsyncStorage.getItem('auth.token')
    
    const client = new ApolloClient({
      link: createUploadLink({
        uri: 'http://localhost:3000/graphql',
        headers: {
          "Some-Custom-Header": token
        }
      }),
      cache: new InMemoryCache()
    })
    

    更新

    const getToken = async () => {
      const token = await AsyncStorage.getItem('auth.token')
      return token
    }
    const token = getToken()
    // Initiate apollo client
    const client = new ApolloClient({
      link: createUploadLink({
        uri: 'http://localhost:3000/graphql',
        headers: {
          authorization: token
        }
      }),
      cache: new InMemoryCache()
    })
    // Wrap apollo provider
    const withProvider = (Component, client) => {
      return class extends React.Component {
        render () {
          return (
            <ApolloProvider client={client}>
              <Component {...this.props} client={client} />
            </ApolloProvider>
          )
        }
      }
    }
    
    export default async () => {
      Navigation.registerComponent('MainScreen', () => withProvider(MainScreen, client))
    
      Navigation.startSingleScreenApp({
        screen: {
          screen: 'MainScreen'
        }
      })
    }
    

    【讨论】:

    • 它几乎可以完美运行。但是,当我从 AsyncStorage 中获取令牌值时,如何设置它?
    • @user3142695 就像在创建 client 之前对代码所做的那样获取它,然后使用该令牌变量作为标头的值
    • 请查看更新后的帖子。我确定它对您来说看起来微不足道,但我不知道如何将令牌从存储中获取到标头。
    • @user3142695 我刚刚更新了我的答案。请看一下,看看它是否适合您。
    • 那么client 没有为Navigation.registerComponent('MainScreen', () =&gt; withProvider(MainScreen, client)) 行定义,该行在export default 函数中使用。
    【解决方案2】:

    我正在使用 apollo boost,我所做的是,

    import ApolloClient from 'apollo-boost';
    
    const client = new ApolloClient({
      uri: 'http://localhost:3000/graphql',
      request: async (operation) => {
        const token = await AsyncStorage.getItem('token');
        operation.setContext({
          headers: {
            authorization: token
          }
        });
      }
    }
    

    【讨论】:

      【解决方案3】:

      getItem 上使用回调也可以

      import { ApolloClient, HttpLink, ApolloLink, InMemoryCache } from 'apollo-boost'
      
      const httpLink = new HttpLink({
        uri: 'http://localhost:4000/graphql',
      })
      
      const authLink = new ApolloLink((operation, forward) => {
        AsyncStorage.getItem('AuthToken').then(token => {
          operation.setContext({
            headers: {
              authorization: token ? `Bearer ${token}` : '',
            },
          })
        })
        return forward(operation)
      })
      
      const apolloClient = new ApolloClient({
        cache: new InMemoryCache(),
        link: authLink.concat(httpLink),
      })
      

      【讨论】:

        【解决方案4】:

        至于 2021 年 6 月,我创建了一个适用于 AsyncStorage 和 React-Redux 的 gist 文件解决方案。如果您不想安装任何其他依赖项,例如apollo-boost,因为您正在使用apollo-client,这是给您的。我希望它也适用于你。

        附言

        此实现用于在您的 apoll-client graphql 请求中设置 tokenauthentication 标头

        【讨论】:

          猜你喜欢
          • 2020-05-14
          • 2018-02-14
          • 2021-02-26
          • 1970-01-01
          • 1970-01-01
          • 2020-06-29
          • 2020-01-06
          • 2020-02-02
          • 1970-01-01
          相关资源
          最近更新 更多