node.js - 如何使用 Apollo 和 React Native 在每个 graphql 请求之前实现自动 jwt token 刷新?

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

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

  1. 用户登录并获取 2 个 token -> 使用 Appollo setContext 将访问 token 放入授权 header 。
  2. 用户向 GraphQL 发出请求 -> 在客户端检查 accessToken 的过期时间: -> 如果未过期 -> 确认请求 -> 如果已过期 -> 调用 GraphQL 刷新 token 突变 -> 获取新 token -> 确认请求。 为了将 token 保留在客户端,我使用KeyChain存储。你能告诉我我是否也应该使用 Apollo 缓存来保存 token 吗?我应该为 token 写 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

最佳答案

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

我认为您不需要关心使用 token 更新 Apollo 缓存,无论是手动还是其他方式,至少有几个原因。首先,考虑到您所存储内容的准敏感性质,最佳实践是采用更安全的存储解决方案,在本例中可能是钥匙串(keychain)。此外,在应用程序中拥有 token 的单一事实来源可以使事情保持干净。

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

关于node.js - 如何使用 Apollo 和 React Native 在每个 graphql 请求之前实现自动 jwt token 刷新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57393078/

相关文章:

node.js - 运行 ng test 时在项目中找不到配置

android - 如何解决Gradle上的(显然不可见的)依赖冲突?

react-native - 如何配置 Amplify 以使用多个 AppSync 端点?

javascript - SetState 被多次调用

Node.js + MongoDB + Express + Mongoose 。如何通过简单的代码要求特定文件夹中的所有模型?

node.js - 测试 Microsoft Bot Framework 异步回复

angular - 在 Angular 6 中处理来自 WebApi 的 400 个错误请求(使用 HttpClient)

string - 如何在 Rust 中将 JSON 字符串转换为 HashMap?

php - 未找到 Lexik JWT token

node.js - LocomotiveJS 服务器端口更改