整合到您自己的伺服器
在您的 backend 加入 token 發行 endpoint,讓瀏覽器端 SDK 取得短效的 session JWT — secret 永遠不會傳到用戶端。
這就是把 選擇您的認證模式 的模式具體實作出來:在您的伺服器上 有一個 token 發行 endpoint,而瀏覽器頁面會在呼叫 SDK 之前先呼叫它。
1. 在您的 backend 加入 token endpoint
import jwt from "jsonwebtoken";
const SECRET = process.env.QURAVIN_SIGNING_SECRET; // 來自「取得您的 API 金鑰」
const APP_ID = "your-app-id"; // 您應用程式的註冊 id
app.get("/ai-token", requireUserLogin, (req, res) => {
const token = jwt.sign(
{
iss: APP_ID,
sub: req.user.id, // 您應用程式中的使用者 id
aud: "quravin",
pipelines: ["translate-string"], // 這位使用者可以呼叫哪些 pipeline
rate_limit: { rpm: 30 },
},
SECRET,
{ algorithm: "HS256", expiresIn: "15m" },
);
res.json({ token, expires_in: 15 * 60 });
});
requireUserLogin 是您自己的驗證中介層 — token 只會發給您伺服器已經驗證過的使用者。
2. 在瀏覽器中取得 token 並呼叫 SDK
<input id="text" />
<button id="go">Translate</button>
<span id="result"></span>
<script src="https://js.quravin.com/v1.js"></script>
<script>
const fetchToken = async () => {
const r = await fetch("/ai-token", { credentials: "include" });
if (!r.ok) throw new Error("Token fetch failed");
return (await r.json()).token;
};
const ai = new Quravin.Quravin({
endpoint: "https://api.example.com/ai-pipeline",
sessionToken: await fetchToken(),
onTokenExpired: fetchToken, // API 回傳 401 時自動更新
});
document.getElementById("go").onclick = async () => {
const out = await ai.run({
pipeline: "translate-string",
inputs: { text: document.getElementById("text").value, target_language: "German" },
});
document.getElementById("result").textContent = out.translation;
};
</script>
3. 處理錯誤
觸及配額或 rate limit 時會回傳型別化的錯誤 — 請向使用者顯示清楚的訊息,並附上 pricing 的連結:
try {
const out = await ai.run({ pipeline: "translate-string", inputs: { /* ... */ } });
} catch (err) {
showToast("Translation failed: " + err.message);
}
到這裡整個流程就完成了:您的伺服器發行 token,瀏覽器永遠看不到 secret,每一次呼叫都會歸屬到實際
發出呼叫的使用者。SDK 還有更完整的參考文件 — 使用 ai.runMany 進行批次處理、ai.button 的 DOM
綁定、raw-prompt 模式,以及完整的疑難排解表 — 若需要更深入的資訊,請洽詢您的平台窗口。