認証
StaticTokenAuth、CallbackAuth、supabaseAuth のいずれかで Nodaro SDK の認証方法を選び、複数のサブドメインで 1 つのブラウザーログインを共有します。
認証プロバイダーは、どのトークンを送るかを Nodaro SDK に伝えます。クライアントはリクエストのたびに、プロバイダーの getToken() を呼び出し、その結果を Authorization: Bearer <token> として送信します。プロバイダーが null を返した場合、リクエストは、匿名のリクエストとしてヘッダーなしで送られます。
プロバイダーを選ぶ
| プロバイダー | 用途 | トークンの出どころ |
|---|---|---|
StaticTokenAuth | サーバーのコード、スクリプト、スケジュールされたジョブ | 固定の API トークンまたは OAuth アクセストークン |
CallbackAuth | 期限があり更新が必要なトークン、独自のセッションストア | あなたの関数(リクエストのたびに呼び出されます) |
supabaseAuth | ユーザーが同じ Nodaro インスタンスにログインするブラウザーアプリ | ユーザーの現在のセッション(自動的に更新されます) |
| 独自のオブジェクト | それ以外のすべて | getToken() メソッドを持つ任意のオブジェクト |
使えるトークン
| トークン | 見た目 | 動作の主体 | 入手先 |
|---|---|---|---|
| API トークン | ndr_ の後に 16 進数 64 文字 | あなた | Nodaro の設定 › APIトークン |
| OAuth アクセストークン | ndr_app_ の後に 16 進数 64 文字 | あなたのアプリを承認したユーザー | OAuth のコード交換、client.oauth.exchangeCode() |
| セッショントークン | ログイン中のセッション | ログイン中のユーザー | supabaseAuth を通じた Nodaro へのログイン |
- API トークンは、利用額の上限がない永続的な認証情報です。無効にするか削除するまで使えるので、サーバーに保管してください。上限とレート設定については、API 認証を参照してください。
- OAuth アクセストークンは、ユーザーが承認したスコープだけを持ちます。あなたのアプリがほかの人の代わりに動作する場合に使います。OAuth を参照してください。
- セルフホスティングの Community エディションのインストール環境では、アプリは API トークンを提供しません。代わりにログインし、
supabaseAuthまたはCallbackAuthでセッショントークンを使ってください。
Auth インターフェース
interface Auth {
getToken(): Promise<string | null>
}この形を持つオブジェクトなら何でも、createClient の auth オプションにできます。以下の 3 つのプロバイダーは、これを実装しています。
StaticTokenAuth
new StaticTokenAuth(token: string)1 つの固定トークンをラップします。プロセスの実行中にトークンが変わらない場合に使います。API トークンや、あなたのサーバーが認可コードフローで取得した OAuth アクセストークンなどです。
Prop
Type
import { createClient, StaticTokenAuth } from "@nodaro/sdk"
const client = createClient({
baseUrl: "https://app.nodaro.ai",
auth: new StaticTokenAuth(process.env.NODARO_TOKEN!),
})CallbackAuth
new CallbackAuth(fn: () => string | null | Promise<string | null>)リクエストのたびにあなたの関数を呼び出し、その関数が返すトークンを送信します。関数は同期でも非同期でもかまいません。トークンなしでリクエストを送るには、null を返します。
Prop
Type
トークンの更新、独自のセッションストアの読み取り、認証情報のローテーションに使います。
import { createClient, CallbackAuth } from "@nodaro/sdk"
const client = createClient({
baseUrl: "https://app.nodaro.ai",
auth: new CallbackAuth(async () => {
const session = await sessionStore.read()
if (!session) return null
if (Date.now() > session.expiresAt - 60_000) {
await refresh(session)
}
return session.accessToken
}),
})supabaseAuth(supabase)
supabaseAuth(supabase: SupabaseLikeClient): Authリクエストのたびに、Supabase v2 クライアントからログイン中のユーザーのトークンを読み取ります。ユーザーが同じ Nodaro インスタンスにログインするブラウザーアプリ、たとえばセルフホスティング環境向けの自作フロントエンドで使います。Nodaro のエディター自体も、同じプロバイダーを使っています。トークンはそのつど読み取られるため、更新されたセッションも自動的に反映されます。
Prop
Type
import { createClient, supabaseAuth } from "@nodaro/sdk"
import { createClient as createSupabase } from "@supabase/supabase-js"
const supabase = createSupabase(
import.meta.env.VITE_SUPABASE_URL,
import.meta.env.VITE_SUPABASE_ANON_KEY,
)
const client = createClient({
baseUrl: import.meta.env.VITE_API_URL ?? "",
auth: supabaseAuth(supabase),
})誰もログインしていない場合、リクエストはトークンなしで送られます。
createSharedSupabaseClient(options)
import { createSharedSupabaseClient } from "@nodaro/sdk/supabase"
createSharedSupabaseClient<Db = any>(options: {
url: string
anonKey: string
cookieDomain?: string
}): SupabaseClient<Db>セッションをローカルストレージではなくクッキーに保存する、ブラウザー用の Supabase クライアントを作成します。cookieDomain を指定すると、同じ親ドメインの下にある複数のサブドメインのアプリが、1 つのログインを共有します。いずれか 1 つでログインすると、すべてでログイン状態になり、いずれか 1 つでログアウトすると、すべてでログアウトします。
Prop
Type
import { createClient, supabaseAuth } from "@nodaro/sdk"
import { createSharedSupabaseClient } from "@nodaro/sdk/supabase"
const supabase = createSharedSupabaseClient({
url: SUPABASE_URL,
anonKey: SUPABASE_ANON_KEY,
cookieDomain: ".example.com",
})
const client = createClient({ baseUrl: "", auth: supabaseAuth(supabase) })cookieDomainが適用されるのは、ページのホストがそのドメインか、そのサブドメインのいずれかである場合だけです。localhostやプレビュー URL など、それ以外のホストでは、クッキーは現在のホストにとどまるため、ローカル開発ではオリジンごとに別々のセッションになります。- 最初の読み込み時に、ローカルストレージにある既存のセッションがクッキーに移され、古いエントリーは削除されます。すでにログインしていたユーザーは、ログイン状態のままになります。期限切れのセッションは破棄されます。
- このエクスポートは、独立したパス
@nodaro/sdk/supabaseにあります。そのため、メインパッケージは Supabase に依存しません。使うには@supabase/supabase-jsと@supabase/ssrをインストールしてください。
スコープと不足している権限
OAuth アクセストークンは、ユーザーが承認したスコープ(workflows:read や workflows:execute など)を持ちます。各リソースのリファレンスページには、そのメソッドが必要とするスコープが明記されています。トークンにスコープが不足している場合、メソッドは ForbiddenError をスローし、その missingScope に不足しているスコープが示されます。
import { ForbiddenError } from "@nodaro/sdk"
try {
await client.workflows.run(workflowId)
} catch (err) {
if (err instanceof ForbiddenError && err.missingScope) {
requestConsentFor([err.missingScope]) // send the user through OAuth again
} else {
throw err
}
}API トークンとセッショントークンは、スコープによる制限を受けません。エラークラスの一覧については、エラーを参照してください。
ブラウザーのルール
- API トークンを決してブラウザーに渡さないでください。ページから誰でも読み取れてしまい、あなたとして動作してしまいます。
- ブラウザーでの OAuth トークンは、あなたの開発者アプリの
allowedOriginsに登録されたオリジンからしか動作しません。OAuth と開発者アプリを参照してください。 supabaseAuthによるセッショントークンは、そのリストと照合されません。- シークレットはサーバーに置いてください。OAuth のコード交換にはクライアントシークレットが必要なので、
client.oauth.exchangeCode()はサーバーのコードでだけ実行してください。
よくある質問
関連ページ
クライアント
OAuth と開発者アプリ
OAuth アプリ
認証
エラー
最終更新