【问题标题】:How to implement auto jwt token refresh before every graphql request with Apollo and React Native?如何在每次使用 Apollo 和 React Native 的 graphql 请求之前实现自动 jwt 令牌刷新?
【发布时间】:2019-12-15 00:18:26
【问题描述】:

我想在 React Native 应用中使用 Apollo 中间件在每次向 GraphQL 发出请求之前实现自动刷新 jwt 令牌。每次用户登录后,他都会获得两个令牌:访问和刷新。访问令牌是在授权标头中使用的 30-60 分钟的简短令牌。刷新令牌是 60 天的长令牌,用于确认刷新令牌 graphql 突变。 我的流程:

  1. 用户登录并获得 2 个令牌 -> 使用 Appollo setContext 将访问令牌放入授权标头。
  2. 用户向 GraphQL 发出请求 -> 在客户端检查 accessToken 的 expireTime: -> 如果它没有过期 -> 确认请求 -> 如果它已过期 -> 调用 GraphQL refreshToken 突变 -> 获取新令牌 -> 确认请求。 为了在客户端保留令牌,我使用 KeyChain 存储。你能告诉我我是否也应该使用 Apollo 缓存来保存令牌?我应该为令牌写 Apollo 状态吗?以及如何实施我的流程?

GraphQL 突变

mutation UpdateTokens($refreshToken: String!, $refreshTokenId: String!) 
 {
    updateTokens(refreshToken: $refreshToken, refreshTokenId: $refreshTokenId) {
      user {
        name
        phone
      }
      accessToken
      refreshToken
    }
  }

App.js

import React from 'react'
import { ApolloClient } from 'apollo-client'
import { ApolloLink } from 'apollo-link'
import { ApolloProvider } from 'react-apollo'
import { ApolloProvider as ApolloHooksProvider } from 'react-apollo-hooks'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { setContext } from 'apollo-link-context'
import * as Keychain from 'react-native-keychain'
import AppNavigator from './AppNavigator'

const httpLink = createHttpLink({
  uri: 'http://localhost:4000'
})

const cache = new InMemoryCache()

const authLink = setContext(async (req, { headers, ...context }) => {
  const tokens = await Keychain.getGenericPassword()
  const accessToken = tokens.username
  return {
    headers: {
      ...headers,
      authorization: accessToken ? `Bearer ${accessToken}` : ''
    },
    ...context
  }
})

const client = new ApolloClient({
  link: ApolloLink.from([authLink, httpLink]),
  cache,
  connectToDevTools: true
})

const App = () => {
  return (
    <ApolloProvider client={client}>
      <ApolloHooksProvider client={client}>
        <AppNavigator />
      </ApolloHooksProvider>
    </ApolloProvider>
  )
}

export default App

【问题讨论】:

标签: node.js react-native jwt graphql apollo-client


【解决方案1】:

老实说,我认为您走在正确的道路上——当我阅读您所需的功能时,我想到了apollo-link-context,并且很高兴看到您采用这种方法。我们最近不得不在一个 react-native 应用程序中实现类似的功能,这需要附加带有身份验证相关数据的自定义标头。为了检索这些数据,我们需要发出一个异步请求,尽管我们的请求是通过网络发送给第三方服务的。就像您一样,我们在客户的setContext 中完成了这一切。这运作良好。

出于某些原因,我认为您不需要手动或以其他方式使用令牌更新 Apollo 缓存。首先,考虑到您所存储内容的准敏感性质,最好的做法是推迟到更安全的存储解决方案,在这种情况下可能是钥匙串。此外,在应用程序中为令牌提供单一事实来源可以保持干净。

假设您不想将此数据写入缓存,我会仔细检查 Apollo 客户端是否不会自动这样做。例如,如果您之前出于某种原因查询了令牌数据,Apollo 可能会在收到突变有效负载后自动更新您的缓存。只是需要注意的事情。

【讨论】:

  • 当然,@jocoders,接受答案并随时欢迎为出色的答案点赞 ;)
猜你喜欢
  • 2020-08-03
  • 1970-01-01
  • 2018-12-18
  • 2014-12-22
  • 2020-05-26
  • 2020-08-25
  • 2020-11-17
  • 2017-05-27
  • 2021-07-02
相关资源
最近更新 更多