为自定义Apollo graphql后端处理Firebase初始化延迟和ID令牌

时间:2019-04-17 17:54:16

标签: reactjs firebase firebase-authentication apollo apollo-link

当前,当我使用Firebase对用户进行身份验证时,我将其身份验证令牌存储在localStorage中,以供以后用于连接到我的后端,如下所示:

const httpLink = new HttpLink({uri: 'http://localhost:9000/graphql'})

const authMiddleware = new ApolloLink((operation, forward) => {
  // add the authorization token to the headers
  const token = localStorage.getItem(AUTH_TOKEN) || null
  operation.setContext({
    headers: {
      authorization: token ? `Bearer ${token}` : ''
    }
  })
  return forward(operation)
})

const authAfterware = onError(({networkError}) => {
  if (networkError.statusCode === 401) AuthService.signout()
})

function createApolloClient() {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: authMiddleware.concat(authAfterware).concat(httpLink)
  })
}

我的问题是,令牌过期后,我无法刷新令牌。因此,我尝试使用以下方法为阿波罗设置授权令牌:

const httpLink = new HttpLink({uri: 'http://localhost:9000/graphql'})

const asyncAuthLink = setContext(
  () => {
    return new Promise((success, reject) => {
      firebase.auth().currentUser.getToken().then(token => {
        success({
          headers: {
            authorization: token ? `Bearer ${token}` : ''
          }
        })
      }).catch(error => {
        reject(error)
      })
    })
  }
)

const authAfterware = onError(({networkError}) => {
  if (networkError.statusCode === 401) AuthService.signout()
})

function createApolloClient() {
  return new ApolloClient({
    cache: new InMemoryCache(),
    link: asyncAuthLink.concat(authAfterware.concat(httpLink))
  })
}

这在用户首次进行身份验证时有效,但是一旦用户刷新页面,当我的graphql查询发送到后端时,firebase将不再初始化,因此令牌不会随它一起发送。有没有一种方法可以让我异步等待firebase.auth().currentUser以便工作呢?还是我应该完全采用另一种方法?据我所知(100%肯定),currentUser.getIdToken仅在当前令牌不再有效时才进行网络呼叫。我认为这是可以接受的,因为在令牌无效的情况下,后端仍然无法响应,因此我将需要等待令牌刷新才能继续。

我想到的其他一些想法:

  • 继续使用localStorage存储auth令牌,如果后端向后发送401响应并重试请求,则在authAfterware中刷新它。
  • 设置获取身份验证令牌的延迟(不理想)
  • 还有其他想法吗?

谢谢!

0 个答案:

没有答案