API anahtarları

OpenAI ve Anthropic konsolları gibi bir yapay zeka ürününün API anahtarları sayfası. Kapsamlı izinler ve son kullanma tarihiyle anahtar oluşturun, gizli anahtarı bir kez görün ve kopyalama onaylansın, geri alınabilir şekilde iptal edin, yerinde yeniden adlandırın, ek süreyle döndürün ve anahtar başına kullanımı görün.

OpenAI, Anthropic ve Vercel'in hepsi aynı API anahtarları sayfasını sunar: yalnızca sonunu görebildiğiniz anahtarların listesi, yenisini oluşturmak için bir iletişim kutusu ve gizli anahtarı kopyalamak için tek bir fırsat. API keys, bu sayfanın herhangi bir Settings bölümüne eklenebilen tek bir blok halidir. Ters gidebilecek kısımları ele alır: bir iletişim kutusu kapandığı için kaybolan gizli anahtarlar, yanlışlıkla iptal edilen anahtarlar ve bir şey çıktığında zıplayan listeler.

Her satır anahtarın adını, hx_live_…a3F9 gibi maskelenmiş gizli anahtarı, izinlerini, projeyi, ne zaman oluşturulduğunu ve en son ne zaman kullanıldığını ya da Never used bilgisini gösterir. Bir hafta içinde süresi dolacak anahtarlar uyarı rozeti alır, süresi dolanlar bunu belirtir. usage iletirseniz geniş ekranlarda anahtarın yanında günlük isteklerin küçük bir grafiği görünür.

Create key; ad, proje, izinler (tümü, salt okunur ya da işaretlediğiniz kaynaklarla sınırlı) ve 30 gün, 90 gün, süresiz ya da seçtiğiniz bir tarihlik son kullanma tarihi içeren bir iletişim kutusu açar. Ardından aynı iletişim kutusu gösterime dönüşür: tam anahtar tek aralıklı bir kutuda, onay işaretiyle doğrulanan bir Copy düğmesi ve Done çalışmadan önce işaretlenecek bir kutu. Kopyalamadan kapatmayı denerseniz uyarı ve Close anyway düğmesiyle açık kalır. Sekme de kapanmadan önce sorar.

İptal etmeden önce anahtarı adıyla anarak sorar. Ardından satır daralarak kaybolur ve bir toast beş saniye boyunca Undo sunar; onRevoke yalnızca bu süre dolunca çalışır, yani Undo sunucunuzdan hiçbir şey gerektirmez. Sayfadan ayrılmak ya da başka bir anahtar oluşturmak bekleyen iptalleri hemen gönderir. Rotate key yeni bir gizli anahtar yerleştirir ve eskisini bir saat, bir gün ya da bir hafta çalışır halde tutabilir. F2 veya çift tıklamayla yerinde yeniden adlandırın, kaydetmek için Enter, vazgeçmek için Escape.

  1. Pro registry'yi components.json dosyasına ekleyin

    components.json
    {
      "registries": {
        "@hextaui-pro": {
          "url": "https://hextaui.com/r/pro/{name}.json",
          "headers": {
            "Authorization": "Bearer ${HEXTAUI_PRO_TOKEN}"
          }
        }
      }
    }
  2. Token'ınızı ekleyin

    Hesap sayfanızda bir token oluşturun ve .env.local dosyasına HEXTAUI_PRO_TOKEN olarak ekleyin.

  3. Bloğu ekleyin

    pnpm dlx shadcn@latest add @hextaui-pro/api-keys

API'nize bağlayın

ApiKeySettings ilettiğiniz anahtarları gösterir ve oluşturma, iptal etme ve yeniden adlandırma için sizi çağırır. Herhangi bir callback'ten hata fırlatın; kullanıcı girdisi korunarak nedeni görür. Liste yüklenirken ApiKeySettingsSkeleton gösterin.

"use client"

import * as React from "react"
import { IconKey } from "@tabler/icons-react"

import { SettingsSection, SettingsShell, type SettingsSectionItem } from "../settings/settings"
import {
  ApiKeySettings,
  ApiKeySettingsSkeleton,
  type ApiKey,
  type ApiKeyInput,
  type ApiKeySecret,
} from "@/components/blocks/api-keys/api-keys"

const sections: SettingsSectionItem[] = [
  { id: "api-keys", label: "API keys", icon: <IconKey /> },
]

async function request<T>(input: string, init?: RequestInit) {
  const response = await fetch(input, {
    ...init,
    headers: { "content-type": "application/json", ...init?.headers },
  })
  if (!response.ok) {
    const body = (await response.json().catch(() => ({}))) as { error?: string }
    throw new Error(body.error ?? "Something went wrong.")
  }
  return (response.status === 204 ? null : await response.json()) as T
}

export function ApiKeysPage() {
  const [keys, setKeys] = React.useState<ApiKey[] | null>(null)
  const [failed, setFailed] = React.useState(false)

  const load = React.useCallback(() => {
    setFailed(false)
    request<{ keys: ApiKey[] }>("/api/keys")
      .then((data) => setKeys(data.keys))
      .catch(() => setFailed(true))
  }, [])

  React.useEffect(load, [load])

  const create = async (input: ApiKeyInput) => {
    const result = await request<ApiKeySecret>("/api/keys", {
      method: "POST",
      body: JSON.stringify(input),
    })
    setKeys((current) => [result.key, ...(current ?? [])])
    return result
  }

  const revoke = async (key: ApiKey) => {
    await request(`/api/keys/${key.id}`, { method: "DELETE" })
    setKeys((current) => current?.filter((item) => item.id !== key.id) ?? null)
  }

  const rename = async (key: ApiKey, name: string) => {
    const updated = await request<ApiKey>(`/api/keys/${key.id}`, {
      method: "PATCH",
      body: JSON.stringify({ name }),
    })
    setKeys((current) => current?.map((item) => (item.id === key.id ? updated : item)) ?? null)
  }

  return (
    <SettingsShell sections={sections} className="h-svh">
      <SettingsSection
        id="api-keys"
        status={failed ? "error" : keys ? "ready" : "loading"}
        skeleton={<ApiKeySettingsSkeleton />}
        onRetry={load}
      >
        <ApiKeySettings
          keys={keys ?? []}
          limit={10}
          onCreate={create}
          onRevoke={revoke}
          onRename={rename}
        />
      </SettingsSection>
    </SettingsShell>
  )
}

Anahtarları sunucunuzda oluşturun

generateApiKey, crypto.getRandomValues kullanır; bu yüzden Node, edge runtime'larında ve Workers'ta çalışır. Bir hash ile son dört karakteri saklayın ve gizli anahtarı yalnızca bir kez geri gönderin.

import { generateApiKey, keyHint, type ApiKey, type ApiKeyInput } from "@/components/blocks/api-keys/api-keys"

async function sha256(value: string) {
  const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value))
  return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("")
}

export async function createKey(
  input: ApiKeyInput,
  save: (record: ApiKey & { hash: string }) => Promise<void>
) {
  const secret = generateApiKey("hx_live_")
  const key: ApiKey = {
    id: crypto.randomUUID(),
    name: input.name.slice(0, 60),
    hint: keyHint(secret),
    permission: input.permission,
    resources: input.resources,
    project: input.project,
    createdAt: new Date().toISOString(),
    lastUsedAt: null,
    expiresAt: input.expiresAt ? new Date(input.expiresAt).toISOString() : null,
  }
  await save({ ...key, hash: await sha256(secret) })
  return { key, secret }
}

Döndürme, kendi kapsamlarınız ve geri alma olmadan

Eski gizli anahtar için ek süreli Rotate key eklemek üzere onRotate iletin. Onaylandığı anda iptal etmek için undoTimeout değerini 0 yapın; API'nize uymak için resources, prefix ve snippet iletin.

"use client"

import { ApiKeySettings, type ApiKey, type ApiKeyOption, type ApiKeySecret } from "@/components/blocks/api-keys/api-keys"

const resources: ApiKeyOption[] = [
  { value: "chat", label: "Chat", description: "Send messages and read replies." },
  { value: "search", label: "Search", description: "Query your indexed documents." },
]

export function RotatingKeys({
  keys,
  api,
}: {
  keys: ApiKey[]
  api: {
    create: (input: unknown) => Promise<ApiKeySecret>
    revoke: (id: string) => Promise<void>
    rotate: (id: string, expireOldInHours: number) => Promise<ApiKeySecret>
  }
}) {
  return (
    <ApiKeySettings
      keys={keys}
      prefix="sk_test_"
      resources={resources}
      undoTimeout={0}
      expiringSoon={14}
      snippet={`curl https://api.example.com/v1/chat \\\n  -H "Authorization: Bearer $EXAMPLE_KEY"`}
      onCreate={(input) => api.create(input)}
      onRevoke={(key) => api.revoke(key.id)}
      onRotate={(key, { expireOldIn }) => api.rotate(key.id, expireOldIn)}
    />
  )
}

Yapı

Dıştan içe doğru birleştirdiğiniz parçalar.

ParçaAçıklama
ApiKeySettingsListe, Create key içeren başlığı, limit notu, boş durum ve tüm iletişim kutuları.
ApiKeySettingsSkeletonSettingsSection'ın skeleton prop'u için listenin şeklini alan bir yükleme yer tutucusu.
generateApiKeycrypto.getRandomValues ile ön ekli rastgele bir anahtar üretir.
keyHintMaskelenmiş anahtar olarak saklanıp gösterilecek, gizli anahtarın son karakterleri.

ApiKeySettings

Ayrıca her div prop'unu kabul eder.

PropTürVarsayılan
keys{ id, name, hint, permission, resources?, project?, createdAt, lastUsedAt?, expiresAt?, usage? }. Tarihler bir Date, ISO dizesi ya da zaman damgası alır. usage günlük isteklerdir, en eskiden başlar.
ApiKey[]–
onCreateAnahtarı oluşturun ve bir kez gösterilen gizli anahtarıyla birlikte döndürün. Mesajı iletişim kutusunda göstermek için hata fırlatın.
(input: ApiKeyInput) => Promise<{ key, secret }>–
onRevokeAnahtarı iptal eder. Geri alma süresinden sonra çalışır. Hata fırlatırsanız anahtar Try again ile geri gelir.
(key) => void | Promise<void>–
onRenameRename, F2 ve çift tıklamayı ekler. Yeni ad hemen görünür ve bu hata fırlatırsa geri alınır.
(key, name) => void | Promise<void>–
onRotateRotate key ekler. expireOldIn, eski gizli anahtarın kaç saat daha çalışmaya devam edeceğidir; hemen kapatmak için 0.
(key, { expireOldIn }) => Promise<{ key, secret }>–
limitİzin verilen en fazla anahtar sayısı. Limitte Create key devre dışı kalır ve not nedenini söyler.
number–
resourcesKısıtlı bir anahtarın kullanmasına izin verilebilecek kaynaklar. Varsayılan olarak models, responses, embeddings, files, agents ve usage.
{ value, label, description? }[]–
projectsOluşturma iletişim kutusuna bir Project seçici ekler ve projeyi her anahtarda gösterir.
{ value, label }[]–
prefixMaskelenmiş anahtarlarda ipucunun önünde gösterilir; anahtarın kendi ön eki varsa o kullanılır.
string"hx_live_"
snippetBoş durumda gösterilen komut, bir Copy düğmesiyle.
string–
undoTimeoutİptalden sonra Undo'nun ms cinsinden ne kadar süre sunulacağı. 0, onaylanır onaylanmaz iptal eder.
number5000
expiringSoonBir anahtarın uyarı rozeti alacağı, son kullanmadan önceki gün sayısı.
number7
nowGöreli tarihler için kullanılan zamanı sabitler; testler ve ekran görüntüleri için.
Date–
PropTürVarsayılan
rowsKaç yer tutucu anahtar gösterileceği.
number3

generateApiKey

Ön ek artı rastgele harf ve rakamlar döndürür.

PropTürVarsayılan
prefixAnahtarın başına eklenir.
string"hx_live_"
lengthÖn ekten sonraki rastgele karakterler, 8 ile 256 arasında.
number40
TuşAction
F2Satırı odakta olan anahtarı yeniden adlandırır.
EnterYeniden adlandırırken adı kaydeder. Oluşturma iletişim kutusunda anahtarı oluşturur.
EscapeYeniden adlandırırken eski adı korur. Gösterimde, anahtar kopyalanmadıysa bir kez uyarır.
TabHer anahtarın eylemleri arasında, ardından iletişim kutusu alanları ve düğmeleri arasında gezinir.
  • Bir anahtar oluşturulduğunda odak Copy'ye geçer ve bir durum mesajı, tekrar gösterilmeyeceği için hemen kopyalanmasını söyler.
  • Onaylar anahtarı ve maskelenmiş gizli anahtarını adıyla anar, odak Cancel üzerinde başlar.
  • İptal sonrası odak sonraki anahtara, yoksa öncekine ya da Create key'e geçer. Undo sonrası geri yüklenen anahtara döner. Yeniden adlandırma sonrası anahtarın eylemlerine döner.
  • Kısıtlı rozetleri kaynaklarını adlandırır, kullanım grafiği toplam olarak okunur, yeniden adlandırmalar ve geri yüklemeler duyurulur.
  • Azaltılmış harekette satırlar daralmadan belirir ve kaybolur.

Şunlarla geliştirildi

API keys bloğunun yapıldığı ücretsiz HextaUI bileşenleri. Her biri tek başına yüklenir.

Kod

4 dosya, components/blocks/api-keys konumuna eklendi.