使用 apollo-client + firebase auth 刷新令牌

Posted

技术标签:

【中文标题】使用 apollo-client + firebase auth 刷新令牌【英文标题】:refreshing a token with apollo-client + firebase auth 【发布时间】:2019-12-01 11:00:23 【问题描述】:

在使用 apollo-client 和 firebase 的身份验证服务时,我无法确定令牌刷新。

我之前使用 apollo 客户端设置了令牌刷新。通常我使用 apollo-link-error 包 (apollo-link-error docs)。

我的理解是你从 firebase auth 获得最新的令牌,并承诺如下:

firebase.auth().currentUser.getIdToken

How to use the Firebase refreshToken to reauthenticate?

阅读this post的答案:

当您从浏览器拨打电话时 .getIdToken(true) 将自动 刷新你的令牌。

根据我上面的阅读,我想出了下面的sn-p

import  onError  from 'apollo-link-error';
import  Observable  from 'apollo-link'; // <-- Add Observable
import firebase from 'lib/firebase';

const errorLink = onError(
  ( graphQLErrors, networkError, operation, forward ) => 

    let accessToken = window.localStorage.getItem('access_token');

    if (graphQLErrors) 
      // User access token has expired
      if (graphQLErrors[0].message.includes('Signature has expired')) 

        if (accessToken && accessToken !== 'undefined') 

          // Let's refresh token through async request
          return new Observable(observer => 
            firebase
              .auth()
              .currentUser.getIdToken(true)
              .then(function(idToken) 
                if (!idToken) 
                  window.localStorage.removeItem('access_token');
                  return console.log('Refresh token has expired');
                

                window.localStorage.setItem('access_token', idToken);

                // reset the headers
                operation.setContext(( headers =  ) => (
                  headers: 
                    // Re-add old headers
                    ...headers,
                    // Switch out old access token for new one
                    'login-token': idToken || null
                  
                ));
                const subscriber = 
                  next: observer.next.bind(observer),
                  error: observer.error.bind(observer),
                  complete: observer.complete.bind(observer)
                ;

                // Retry last failed request
                forward(operation).subscribe(subscriber);
              )
              .catch(error => 
                // No refresh or client token available, we force user to login
                observer.error(error);
              );
          );
        
      
    
  
);

export default errorLink;

【问题讨论】:

除了等待一个小时让它过期之外,还有一种简单的方法来测试令牌过期吗?更改客户端上的时间没有做任何有意义的事情,我正在使用服务来托管我的服务器,所以我不知道如何更改时间。我还有什么遗漏的吗? @BrandonM 我现在尝试使用accountJS...我不惜一切代价避免使用auth0和firebase 【参考方案1】:

上面的代码确实有效!

我的问题在这里:

if (graphQLErrors[0].message.includes('Signature has expired'))

我的服务器的错误信息实际上是“令牌已过期”。我改变了我上面的 if 语句,一切都很好!

我没有在网上找到很多 apollo-client+firebase-auth 的例子,所以希望这个面包屑可以帮助其他人在使用 apollo-client 和 firebase auth 时。

【讨论】:

我在这里遇到了一个后续问题,它会刷新直到刷新令牌过期。那时,服务器错误不断出现,我的 UI 错误也出现了……不知道如何处理。

以上是关于使用 apollo-client + firebase auth 刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

使用 Apollo-Client 重新获取查询会引发错误

如何为 apollo-client 的每个请求设置变量?

使用 React 钩子处理 graphQL 突变错误(useMutation + Apollo-client)

无法理解 apollo-client 中解析器的使用

使用 GET/HEAD 方法的请求不能有正文 APOLLO-CLIENT

使用 Apollo-Client 对 GitHub API v4 进行身份验证