setup-flows-auth

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Set Up Flows Authentication

配置Flows认证

Wire a React app for Flows auth so it can talk to CDF inside Fusion. Two flows exist; pick one based on
app.json
.
为React应用配置Flows认证,使其能在Fusion内部与CDF通信。存在两种流模式,需根据
app.json
选择。

Pick the flow

选择流模式

Read
app.json
if present:
app.json
infra
FlowAuth sourceExtra package
"appsApi"
Apps API (new Fusion app host)
connectToHostApp
from
@cognite/app-sdk
@cognite/app-sdk
missing / otherClassic (legacy Files API)
DuneAuthProvider
+
useDune()
from
@cognite/dune
No
app.json
? Ask the user. Default to Apps API — it's the default for
npx @cognite/dune create
.
若存在
app.json
,请读取该文件:
app.json
infra
字段
流模式认证来源额外包
"appsApi"
Apps API(新版Fusion应用宿主)
@cognite/app-sdk
中的
connectToHostApp
@cognite/app-sdk
缺失/其他值经典模式(旧版Files API)
@cognite/dune
中的
DuneAuthProvider
+
useDune()
若没有
app.json
?请询问用户。默认选择Apps API——这是
npx @cognite/dune create
的默认模式。

Step 1 — Read state, decide whether to act

步骤1 — 读取状态,判断是否需要执行操作

Read
package.json
,
src/main.tsx
(or
src/index.tsx
),
vite.config.ts
,
app.json
.
A valid setup already exists if any of these is true — in which case do nothing and report no-op:
  • Classic:
    <DuneAuthProvider>
    from
    @cognite/dune
    wraps
    <App />
    in the entry file.
  • Apps API, generator pattern:
    connectToHostApp
    from
    @cognite/app-sdk
    is called inside
    App.tsx
    (or any component) and feeds the auth state into the rest of the app.
  • Apps API, wrapper pattern:
    <AppSdkAuthProvider>
    from
    @cognite/dune
    wraps
    <App />
    in the entry file. (This is a valid alternative — same
    useDune()
    API as classic, less boilerplate. Don't try to "fix" it back to the generator default.)
Detect the package manager from the lock file (
pnpm-lock.yaml
→ pnpm,
yarn.lock
→ yarn, otherwise npm).
读取
package.json
src/main.tsx
(或
src/index.tsx
)、
vite.config.ts
app.json
若满足以下任一条件,则表示已存在有效配置——此时无需执行任何操作,并告知用户无操作:
  • 经典模式:入口文件中
    <DuneAuthProvider>
    (来自
    @cognite/dune
    )包裹了
    <App />
  • Apps API生成器模式
    App.tsx
    (或任意组件)中调用了
    @cognite/app-sdk
    connectToHostApp
    ,并将认证状态传入应用其余部分。
  • Apps API包裹器模式:入口文件中
    <AppSdkAuthProvider>
    (来自
    @cognite/dune
    )包裹了
    <App />
    。(这是一种有效的替代方案——与经典模式使用相同的
    useDune()
    API,样板代码更少。无需将其“修复”回默认的生成器模式。)
通过锁文件检测包管理器(
pnpm-lock.yaml
→ pnpm,
yarn.lock
→ yarn,否则为npm)。

Step 2 — Install missing deps

步骤2 — 安装缺失的依赖

Required for both flows:
PackageType
@cognite/dune
runtime (provides Vite plugin even in Apps API mode)
@cognite/sdk
runtime
@tanstack/react-query
runtime
vite-plugin-mkcert
dev
Apps API only, also install:
PackageType
@cognite/app-sdk
runtime
Skip anything already in
package.json
. Use the detected package manager (
pnpm add
,
npm install
,
yarn add
;
-D
/
--save-dev
for dev deps).
两种流模式均需安装:
类型
@cognite/dune
运行时(即使在Apps API模式下也提供Vite插件)
@cognite/sdk
运行时
@tanstack/react-query
运行时
vite-plugin-mkcert
开发依赖
仅Apps API模式还需安装:
类型
@cognite/app-sdk
运行时
跳过已在
package.json
中的包。使用检测到的包管理器(
pnpm add
npm install
yarn add
;开发依赖需添加
-D
/
--save-dev
参数)。

Step 3 — Vite config

步骤3 — Vite配置

vite.config.ts
must contain:
ts
import { fusionOpenPlugin } from "@cognite/dune/vite";
import mkcert from "vite-plugin-mkcert";

export default defineConfig({
  base: "./",
  plugins: [react(), mkcert(), fusionOpenPlugin(), /* ... */],
  server: { port: 3001 },
  worker: { format: "es" },
});
  • base: "./"
    — required for Fusion iframe deployment.
  • mkcert()
    — provides HTTPS for the dev server (the Fusion parent is HTTPS).
  • fusionOpenPlugin()
    — opens the dev URL inside Fusion automatically.
  • server.port: 3001
    — convention; the plugin falls back to 3001 if no port is set.
Add only what's missing. Don't remove existing plugins.
vite.config.ts
必须包含以下内容:
ts
import { fusionOpenPlugin } from "@cognite/dune/vite";
import mkcert from "vite-plugin-mkcert";

export default defineConfig({
  base: "./",
  plugins: [react(), mkcert(), fusionOpenPlugin(), /* ... */],
  server: { port: 3001 },
  worker: { format: "es" },
});
  • base: "./"
    — Fusion iframe部署必需。
  • mkcert()
    — 为开发服务器提供HTTPS(Fusion宿主为HTTPS)。
  • fusionOpenPlugin()
    — 自动在Fusion内部打开开发URL。
  • server.port: 3001
    — 约定;若未设置端口,插件会回退到3001。
仅添加缺失的内容,不要移除现有插件。

Step 4 — Wire up the entry file and component

步骤4 — 配置入口文件与组件

Classic flow

经典模式

src/main.tsx
:
tsx
import { DuneAuthProvider } from "@cognite/dune";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";

const queryClient = new QueryClient({
  defaultOptions: { queries: { staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000 } },
});

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <DuneAuthProvider>
        <App />
      </DuneAuthProvider>
    </QueryClientProvider>
  </React.StrictMode>
);
In components, use
useDune()
:
tsx
import { useDune } from "@cognite/dune";

const { sdk, isLoading, error } = useDune();
// sdk is an authenticated CogniteClient
src/main.tsx
tsx
import { DuneAuthProvider } from "@cognite/dune";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";

const queryClient = new QueryClient({
  defaultOptions: { queries: { staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000 } },
});

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <DuneAuthProvider>
        <App />
      </DuneAuthProvider>
    </QueryClientProvider>
  </React.StrictMode>
);
在组件中使用
useDune()
tsx
import { useDune } from "@cognite/dune";

const { sdk, isLoading, error } = useDune();
// sdk为已认证的CogniteClient

Apps API flow (generator default)

Apps API模式(生成器默认)

src/main.tsx
does not wrap in any auth provider — auth is handled inside
App.tsx
:
tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";

const queryClient = new QueryClient({
  defaultOptions: { queries: { staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000 } },
});

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>
);
src/App.tsx
calls
connectToHostApp
from
@cognite/app-sdk
. The handshake is async, so render a loader until it resolves:
tsx
import { connectToHostApp } from "@cognite/app-sdk";
import { useEffect, useState } from "react";

function App() {
  const [project, setProject] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | undefined>();

  useEffect(() => {
    let cancelled = false;
    connectToHostApp({ applicationName: "<your-app-name>" })
      .then(async ({ api }) => {
        if (cancelled) return;
        setProject(await api.getProject());
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : String(err));
      })
      .finally(() => {
        if (!cancelled) setIsLoading(false);
      });
    return () => { cancelled = true; };
  }, []);

  // render isLoading / error / authenticated UI
}
Use
applicationName: appConfig.externalId
(from
app.json
) so the host can identify the app.
src/main.tsx
使用任何认证提供程序包裹——认证在
App.tsx
内部处理:
tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.tsx";

const queryClient = new QueryClient({
  defaultOptions: { queries: { staleTime: 5 * 60 * 1000, gcTime: 10 * 60 * 1000 } },
});

ReactDOM.createRoot(document.getElementById("root")!).render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>
);
src/App.tsx
调用
@cognite/app-sdk
connectToHostApp
。握手过程为异步操作,因此在解析完成前需渲染加载器:
tsx
import { connectToHostApp } from "@cognite/app-sdk";
import { useEffect, useState } from "react";

function App() {
  const [project, setProject] = useState<string | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | undefined>();

  useEffect(() => {
    let cancelled = false;
    connectToHostApp({ applicationName: "<your-app-name>" })
      .then(async ({ api }) => {
        if (cancelled) return;
        setProject(await api.getProject());
      })
      .catch((err: unknown) => {
        if (cancelled) return;
        setError(err instanceof Error ? err.message : String(err));
      })
      .finally(() => {
        if (!cancelled) setIsLoading(false);
      });
    return () => { cancelled = true; };
  }, []);

  // 渲染加载中/错误/已认证UI
}
使用
applicationName: appConfig.externalId
(来自
app.json
),以便宿主识别应用。

Apps API flow — wrapper alternative

Apps API模式——包裹器替代方案

If the project already uses
<AppSdkAuthProvider>
from
@cognite/dune
, leave it. It wraps the same
connectToHostApp
handshake and gives a
useDune()
API identical to the classic flow. Both patterns are valid for Apps API mode.
若项目已使用
@cognite/dune
<AppSdkAuthProvider>
,请保留该配置。它封装了相同的
connectToHostApp
握手流程,并提供与经典模式完全一致的
useDune()
API。两种模式在Apps API下均有效。

Step 5 — Clean up superseded code

步骤5 — 清理过时代码

Remove only what's now redundant:
  • Custom CDF auth providers/hooks
  • Manual
    CogniteClient
    instantiation
  • OIDC/token-management code
  • CDF env vars (
    VITE_CDF_PROJECT
    ,
    VITE_CDF_CLUSTER
    , etc.) — Flows/the host provide these
If unsure, leave it and flag to the user.
仅移除现在冗余的代码:
  • 自定义CDF认证提供程序/钩子
  • 手动实例化
    CogniteClient
  • OIDC/令牌管理代码
  • CDF环境变量(
    VITE_CDF_PROJECT
    VITE_CDF_CLUSTER
    等)——Flows/宿主会提供这些变量
若不确定,请保留代码并告知用户。