Cloudflare Workers برای توسعهدهندگان ASP.NET Core؛ بخش دوم: ورکرها بهعنوان یک لایه میانی
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۵/۲۲ ۰۸:۱۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
Request -> Middleware 1 -> Middleware 2 -> ... -> Endpoint (Controller/Minimal API) -> ... -> Middleware 2 -> Middleware 1 -> ResponseUser Request -> Cloudflare Edge (Worker) -> [Internet] -> Your ASP.NET Core Server (Origin) -> [ASP.NET Core Middleware Pipeline]| ویژگی | Middleware در ASP.NET Core | Cloudflare Workers (به عنوان Middleware) |
| محل اجرا | روی سرور اصلی (Origin) | شبکه جهانی کلادفلر (نزدیک به کاربر) |
| زبان و محیط | C# / .NET Runtime | JavaScript, TypeScript / V8 Isolates |
| تأثیر بر عملکرد | پردازش آن به زمان پاسخ سرور اضافه میکند | با پردازش زود هنگام، زمان پاسخ نهایی را کاهش میدهد |
| حوزه تأثیر | محدود به همان اپلیکیشن | میتواند روی یک دامنه کامل (شامل چندین اپلیکیشن) اعمال شود |
| دسترسیها | دسترسی کامل به DI، دیتابیس و منطق برنامه | دسترسی به سرویسهای Edge (KV, R2) و APIهای خارجی |
| هزینه | هزینه CPU و RAM سرور اصلی شما را مصرف میکند | هزینه بر اساس تعداد درخواستها محاسبه میشود |
DbContext, ILogger).Microsoft.AspNetCore.Authentication.JwtBearer استفاده کرده و با افزودن [Authorize] روی کنترلرها، توکن JWT را روی سرور خودتان اعتبارسنجی میکنید.jose استفاده میکنیم:npm install jose
secrets.json یا Azure Key Vault در دنیای .NET است.wrangler secret put JWT_SECRET # سپس کلید خود را paste کنید
env در دسترس خواهد بود.import { jwtVerify } from 'jose';
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// ۱. توکن را از هدر استخراج کن
const authHeader = request.headers.get('Authorization');
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return new Response('Missing or invalid Authorization header', { status: 401 });
}
const token = authHeader.substring(7);
try {
// ۲. کلید امن را به فرمت صحیح تبدیل کن
const secret = new TextEncoder().encode(env.JWT_SECRET);
// ۳. توکن را اعتبارسنجی کن
await jwtVerify(token, secret);
// ۴. اگر معتبر بود، درخواست را به سرور اصلی بفرست
return fetch(request); // Pass through to the origin server
} catch (error) {
// ۵. اگر نامعتبر بود، دسترسی را مسدود کن
return new Response('Invalid token', { status: 401 });
}
},
};
interface Env {
JWT_SECRET: string;
}app.UseCors() را در Program.cs فراخوانی کرده و پالیسیهای مختلفی را تعریف میکنید.OPTIONS (که به pre-flight request معروفند) در Edge پاسخ داده میشوند و هرگز به سرور شما نمیرسند و بار اضافی ایجاد نمیکنند.export default {
async fetch(request: Request): Promise<Response> {
// لیست دامنههای مجاز
const allowedOrigins = ['https://my-frontend-app.com', 'http://localhost:3000'];
const origin = request.headers.get('Origin');
// اگر دامنه درخواستکننده مجاز است، هدرها را تنظیم میکنیم
const corsHeaders: { [key: string]: string } = {
'Access-Control-Allow-Methods': 'GET,HEAD,POST,OPTIONS',
'Access-Control-Max-Age': '86400',
'Access-Control-Allow-Headers': request.headers.get('Access-Control-Request-Headers') || '',
};
if (origin && allowedOrigins.includes(origin)) {
corsHeaders['Access-Control-Allow-Origin'] = origin;
}
// ۱. به درخواستهای pre-flight در Edge پاسخ بده
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// ۲. برای سایر درخواستها، ابتدا به سرور اصلی برو
const response = await fetch(request);
// ۳. یک کپی قابل تغییر از پاسخ بساز
const mutableResponse = new Response(response.body, response);
// ۴. هدرهای CORS را به پاسخ نهایی اضافه کن
for (const key in corsHeaders) {
mutableResponse.headers.set(key, corsHeaders[key]);
}
return mutableResponse;
},
};export default {
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
const versionA_Host = 'api-stable.mydomain.com';
const versionB_Host = 'api-beta.mydomain.com';
// بر اساس یک معیار (مثلاً شانس)، هاست مقصد را انتخاب کن
if (Math.random() < 0.5) {
url.hostname = versionA_Host;
} else {
url.hostname = versionB_Host;
}
// درخواست را با هاست جدید به مقصد بفرست
return fetch(new Request(url, request));
},
};export default {
async fetch(request: Request): Promise<Response> {
// یک کپی قابل تغییر از هدرها بساز
const newHeaders = new Headers(request.headers);
// اطلاعات کشور کاربر را به هدرها اضافه کن
if (request.cf && request.cf.country) {
newHeaders.set('X-User-Country', request.cf.country as string);
}
// یک درخواست جدید با هدرهای تغییر یافته بساز و به سرور اصلی بفرست
const newRequest = new Request(request.url, {
...request,
headers: newHeaders,
});
return fetch(newRequest);
},
};X-User-Country) را بخوانید و از آن استفاده کنید.