使用 Apollo/graphQL/React 访问和刷新令牌

2024-01-20

经过长时间的搜索,当访问令牌过期时,我为我的应用程序制定了这个解决方案。与其他服务的区别在于,我必须使用外部服务,在使用我的谷歌帐户登录时为我提供访问和刷新令牌。然后,当访问令牌过期时,我需要检索刷新令牌,将其发送到为我提供新访问和刷新令牌的服务。我见过一些实现,您不会等待收到 401 错误,而是计算令牌过期之前的时间并发送请求,以及处理待处理请求的其他实现。这将是一个用于管理我们的资产的内部应用程序,因此我预计单个用户不会有很多并发查询/请求,因此我避免了处理待处理请求的部分。 不幸的是,目前我无法尝试,因为该服务要到明年才能提供,但我想问一下它是否正确或者我是否需要添加更多逻辑

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { AppProvider } from "./context";
import {
  ApolloProvider,
  ApolloClient,
  ApolloLink,
  createHttpLink,
  InMemoryCache,
  from,
  fromPromise,
} from "@apollo/client";
import { setContext } from "@apollo/client/link/context";
import { onError } from "@apollo/client/link/error";
const axios = require("axios").default;

const httpLink = createHttpLink({
  uri: "http://localhost:4000",
});

const authLink = new ApolloLink((operation, forward) => {
  const accessToken = localStorage.getItem("accessToken");

  operation.setContext(({ headers }) => ({
    headers: {
      ...headers,
      authorization: accessToken ? `Bearer ${accessToken}` : "",
    },
  }));

  return forward(operation);
});

const getNewToken = async () => {
  try {
    const { data } = await axios.post(
      "https://xxx/api/v2/refresh",
      { token: localStorage.getItem("refreshToken") }
    );
    localStorage.setItem("refreshToken", data.refresh_token);
    return data.access_token;
  } catch (error) {
    console.log(error);
  }
};

const errorLink = onError(
  ({ graphQLErrors, networkError, operation, forward }) => {
    if (graphQLErrors) {
      for (let err of graphQLErrors) {
        switch (err.statusCode) {
          case 401:
            return fromPromise(
              getNewToken().catch((error) => {
                // Handle token refresh errors e.g clear stored tokens, redirect to login
                return;
              })
            )
              .filter((value) => Boolean(value))
              .flatMap((accessToken) => {
                const oldHeaders = operation.getContext().headers;
                // modify the operation context with a new token
                operation.setContext({
                  headers: {
                    ...oldHeaders,
                    authorization: `Bearer ${accessToken}`,
                  },
                });

                // retry the request, returning the new observable
                return forward(operation);
              });
        }
      }
    }
  }
);

const client = new ApolloClient({
  link: from[(authLink, errorLink, httpLink)],
  cache: new InMemoryCache(),
});

ReactDOM.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <AppProvider>
        <App />
      </AppProvider>
    </ApolloProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Apollo/graphQL/React 访问和刷新令牌 的相关文章

随机推荐

  • 使用 DAG 的 Condor 作业以及一些需要运行同一主机的作业

    我有一个计算任务 它被分成几个具有依赖性的单独程序执行 我使用 Condor 7 作为任务调度程序 使用 Vanilla Universe 由于对程序的限制超出了我的能力范围 因此不涉及检查点 因此 DAG 看起来像是一个自然的解决方案 然
  • 在 Delphi XE 中使用通用容器 - 总是吗?

    当拥有一个项目以及这些项目的强类型列表时 通用容器可以节省时间 它节省了创建可能带有 TList 内部变量的新类的重复编码 以及类型化的 Add Delete 类型方法 以及其他好处 例如通用容器类提供的所有新功能 但是 是否建议以后始终对
  • 如何更改 WPF ComboBox 中选定文本的颜色?

    在我的应用程序中 我为 TextBlock 定义了以下样式
  • 使用 PHP 将数据添加到 csv 文件的特定列中

    我有一个 csv 文件 有 14 列和数百行 有一个标题是 sku category description brand etc 所有数据都已存在 但我正在尝试在 CSV 中的某些特定列中添加一些图像文件名 images small ima
  • 连接多个字符串与 String.Format [重复]

    这个问题在这里已经有答案了 这里有两种结果相同的方法 public class MessageManager public void SendMessage string name int count string message Hi n
  • 使用 TLS 的 node.js mqtt 客户端

    我正在尝试使用下面的包来实现带有 TLS 的 node js mqtt 客户端 https www npmjs com package mqtt client https www npmjs com package mqtt client
  • 将字符串格式的 url 的 DataFrame 正确转换为 JSON

    我有一个包含 2 列的数据框 其中一列由 URL 组成 示例代码 df pd DataFrame columns name image df df append name sample name image https images pex
  • 元组列表到数据帧的转换[重复]

    这个问题在这里已经有答案了 我有一个类似于以下内容的元组列表 date1 ticker1 value1 date1 ticker1 value2 date1 ticker1 value3 我想将其转换为 DataFrameindex dat
  • 如何在PHP中获取新推送项目的数字键?

    arr new item 是否可以通过编程方式获取新推送的项目 请注意 这不是必需的count arr 1 arr 1 2 arr new item 在上面的例子中 就是2 end 完成工作 返回价值 如果对你有帮助 您可以使用key 之后
  • RuntimeBinderException - C# .NET 4 动态关键字 - 帮助我理解为什么方法不匹配

    我为 HttpModule 构建了一个通用配置系统 允许可插入的 HTTP 标头检查器 作为参考 这里是代码的基本布局 这应该足以让我了解我正在做的事情 public interface IHttpHeaderInspectingAuthe
  • 如何为我的 Java 应用程序指定一个唯一的进程名称?

    我注意到 当我启动 Netbeans 时 它在任务管理器中显示为netbeans exe因为我自己的所有 Java 应用程序都显示为java exe or javaw exe 我怎样才能改变它 以便我的进程名称显示为myapp exe 进程
  • 在 R 中创建空间数据

    我有一个 100 x 200 米区域内物种及其大致位置的数据集 数据框的位置部分不是我认为可用的格式 在这个 100 x 200 米的矩形中 有 200 个 10 x 10 米的正方形 分别命名为 A 到 CV 每个 10 x 10 的正方
  • 如何动态添加导航栏到 jQuery Mobile 应用程序

    如何动态地将导航栏添加到我的 jquery 移动应用程序中 我希望能够从 javascript 将导航栏元素添加到 dom 然后解析它们 我发现我可以根据需要将元素添加到 DOM 然后在元素上调用 navbar 它将执行导航栏解析 例如我可
  • Ormlite Android 批量插入

    谁能解释一下为什么我的插入在 Ormlite 中花费了这么长时间 在桌面上的一个 SQLite 事务中执行 1 700 次插入只需不到一秒 然而 当使用 Ormlite for Android 时 大约需要 70 秒 并且我可以在调试消息中
  • .NET几何库[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在 NET 中启动一个新项目 该项目需要一些几何算法 例如 检查点是否在多边形内部 贝塞尔曲线 线交
  • 在 C# 类库中使用 MATLAB MWArray.dll

    我正在尝试使用 dll 在 MATLAB 中使用 Matlab net Complier 构建 C 类库 但是每次初始化 MWArray dll 中的对象时程序都会引发异常 例如 MWNumericArray m new MWNumeric
  • json.dump 在看似有效的对象上抛出“TypeError:{...} 不是 JSON 可序列化”?

    背景 我正在编写一个 python 程序来管理我的音乐文件 它抓取目录并将文件及其元数据 通过诱变剂 以 JSON 编码 作为简单的 数据库 放入文件中 我的目录搜索很好 但是当我尝试保存数据库或编码为 JSON 时 它会抛出 TypeEr
  • 维护 web.config 文件

    我很想知道其他人如何维护已部署应用程序的 web config 文件 假设没有自动部署机制 这超出了这个问题的范围 因此 在开发过程中 一些开发人员可能会利用 web config 转换 构建 发布他们的项目 调试 发布 测试 实时配置 然
  • 如何撤消clearPackagePreferredActivities("com.android.launcher");

    我想做的是复制 ToddlerLock 应用程序的功能 我已经设法清除默认启动器 PackageManager localPackageManager getPackageManager localPackageManager clearP
  • 使用 Apollo/graphQL/React 访问和刷新令牌

    经过长时间的搜索 当访问令牌过期时 我为我的应用程序制定了这个解决方案 与其他服务的区别在于 我必须使用外部服务 在使用我的谷歌帐户登录时为我提供访问和刷新令牌 然后 当访问令牌过期时 我需要检索刷新令牌 将其发送到为我提供新访问和刷新令牌