پرش به محتوا
بناBana UI

حالت نمایش

پالت رنگی

با ↑ ↓ جابه‌جا شوید و Enter را بزنید. Esc برای بستن.

Adapterهای Backend

پوشه‌ی server/ بدون هیچ وابستگی (فقط node:crypto)، سمت سرورِ درخواست‌هایی را که ماژول‌های مرورگر می‌فرستند پوشش می‌دهد: نشانه‌ی CSRF وابسته به نشست، بررسی Origin، Idempotency-Key با پاسخ تکراری، محدودیت نرخ، همان Schema برای اعتبارسنجی، تشخیص نوع واقعی فایل و هدرهای امنیتی سازگار با Bana.

ورودیبرای
@bana-ui/core/serverهسته: createGuard، verifyFile، securityHeaders، fieldErrors
@bana-ui/core/server/expressExpress و Connect
@bana-ui/core/server/fetchهر چیز با Request → Response: Next.js، Hono، Deno، Bun، Cloudflare
@bana-ui/core/server/fastifyFastify
کد
import express from "express";
import { createGuard, securityHeaders } from "@bana-ui/core/server";
import { banaExpress, banaValidate } from "@bana-ui/core/server/express";
import schema from "./signup.schema.json" with { type: "json" };   // the same file the browser renders

const guard = createGuard({ secret: process.env.BANA_SECRET });   // 32+ random characters

const app = express();
app.use((req, res, next) => { res.set(securityHeaders()); next(); });
app.use(express.json());
app.use(banaExpress(guard));                                      // CSRF + Idempotency-Key + Origin

app.get("/", (req, res) => res.send(`<meta name="csrf-token" content="${req.bana.csrfToken}">…`));
app.post("/api/signup", banaValidate(guard, schema), (req, res) => {
  const user = save(req.bana.values);        // cleaned: Latin digits, ی/ک, hidden fields omitted
  res.status(201).json({ ok: true, id: user.id });
});                                           // invalid → 422 { errors: { field: message } } shown under each field
کد
// Next.js / Hono / Deno / Bun
export const POST = withBana(guard, { session: (req) => sidFromCookie(req), schema },
  async (req, { values }) => Response.json({ ok: true }, { status: 201 }));

// Fastify
await app.register(banaFastify, { guard });
app.post("/api/signup", { preValidation: banaFastify.validate(guard, schema) }, async (req) => ({ ok: true }));
پاسخوقتی
403نشانه‌ی CSRF نادرست/منقضی/متعلق به نشست دیگر، Origin ناشناس، یا Sec-Fetch-Site: cross-site
409 / 422درخواست هم‌کلید هنوز در حال پردازش است / همان کلید با بدنه‌ی دیگر
429محدودیت نرخ؛ هدر Retry-After را مرورگر (Safe Action) رعایت می‌کند
همان پاسخ + Idempotent-Replayedتلاش مجدد با همان Idempotency-Key و همان بدنه؛ کد شما دوباره اجرا نمی‌شود
این لایه جایگزین Authentication و Authorization نیست.شناسه‌ی نشست (session) باید از سیستم ورود خودتان بیاید؛ اگر ندهید یک کوکی ناشناس __Host-bana-sid ساخته می‌شود (در توسعه‌ی HTTP ساده cookie: { secure: false } بدهید). حافظه‌ی پیش‌فرض Idempotency و محدودیت نرخ داخل پردازش است؛ با چند سرور یا ری‌استارت از دست می‌رود، پس store / rateStore را به Redis یا پایگاه‌داده وصل کنید. آدرس IP پشت پروکسی را خودتان درست تنظیم کنید. verifyFile فقط چند نوع رایج (PNG، JPEG، GIF، WebP، PDF، ZIP) را از روی بایت‌ها می‌شناسد و تجزیه‌ی multipart (مثلاً busboy) با شماست.

برای کار با CSP سخت‌گیرانه، اسکریپت راه‌اندازی را فایل بیرونی بگذارید (import { Bana } from "/bana.js"; Bana.start();)؛ خود Bana هیچ اسکریپت یا استایل درون‌خطی لازم ندارد.

ویرایش این صفحه در GitHub