From 67cfdb6df2a707d9891cded054f02ae85959e9bb Mon Sep 17 00:00:00 2001 From: Goodman74 Date: Mon, 11 May 2026 17:39:11 +0300 Subject: [PATCH] feat(cors): Run frontend and backend on different origins - frontend - add API http wrapper - add .env configuration - configure custom frontend host - backend - configure custom backend host - configure CORS policy --- .gitignore | 1 - backend/PromoCodeFactory.WebHost/Program.cs | 13 +++++++++++++ .../Properties/launchSettings.json | 16 ++++++++-------- frontend/.env | 1 + frontend/src/common/http.ts | 5 +++++ .../src/components/private/PartnerLimits.tsx | 3 ++- .../src/components/private/PartnerProfile.tsx | 3 ++- frontend/src/components/public/FetchApi.tsx | 3 ++- frontend/vite.config.ts | 2 ++ 9 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 frontend/.env create mode 100644 frontend/src/common/http.ts diff --git a/.gitignore b/.gitignore index 2182670..3e938c5 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,6 @@ _ReSharper*/ ### .NET / ASP.NET Core # Keep base appsettings.json in repo; ignore local/env-specific appsettings.Development.json -.env # DP keys Api docker/dpkeys/*.xml diff --git a/backend/PromoCodeFactory.WebHost/Program.cs b/backend/PromoCodeFactory.WebHost/Program.cs index 75d6ff3..0a24a38 100644 --- a/backend/PromoCodeFactory.WebHost/Program.cs +++ b/backend/PromoCodeFactory.WebHost/Program.cs @@ -13,6 +13,17 @@ builder.Services.AddOpenApi(builder.Environment); +builder.Services.AddCors(options => +{ + options.AddPolicy("Frontend", policy => + { + policy + .WithOrigins("http://app.test.me:5173") + .AllowAnyHeader() + .AllowAnyMethod(); + }); +}); + var app = builder.Build(); app.UseExceptionHandler(); @@ -20,6 +31,8 @@ app.MapOpenApi(); app.MapSwaggerUI(); +app.UseCors("Frontend"); + app.MapControllers(); app.MigrateDatabase(); diff --git a/backend/PromoCodeFactory.WebHost/Properties/launchSettings.json b/backend/PromoCodeFactory.WebHost/Properties/launchSettings.json index fe6da2f..e9628da 100644 --- a/backend/PromoCodeFactory.WebHost/Properties/launchSettings.json +++ b/backend/PromoCodeFactory.WebHost/Properties/launchSettings.json @@ -1,14 +1,14 @@ { "profiles": { "PromoCodeFactory.WebHost": { - "commandName": "Project", - "launchUrl": "swagger", - "dotnetRunMessages": true, - "launchBrowser": true, - "applicationUrl": "https://localhost:8090;http://localhost:8091", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } + "commandName": "Project", + "launchUrl": "swagger", + "dotnetRunMessages": true, + "launchBrowser": true, + "applicationUrl": "https://api.test.me:8090;http://api.test.me:8091", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } } } } diff --git a/frontend/.env b/frontend/.env new file mode 100644 index 0000000..7723b1f --- /dev/null +++ b/frontend/.env @@ -0,0 +1 @@ +VITE_API_BASE_URL=http://api.test.me:8091 diff --git a/frontend/src/common/http.ts b/frontend/src/common/http.ts new file mode 100644 index 0000000..c55a67e --- /dev/null +++ b/frontend/src/common/http.ts @@ -0,0 +1,5 @@ +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; + +export async function apiFetch(path: string, init?: RequestInit) { + return fetch(`${API_BASE_URL}${path}`, init); +} diff --git a/frontend/src/components/private/PartnerLimits.tsx b/frontend/src/components/private/PartnerLimits.tsx index 9ea3046..4b716c6 100644 --- a/frontend/src/components/private/PartnerLimits.tsx +++ b/frontend/src/components/private/PartnerLimits.tsx @@ -6,6 +6,7 @@ import type { UiState } from "../../common/types"; import { PartnerSchema, type PartnerDto } from "../public/zodType"; import { ResultBlock } from "../common/ResultBlock"; import { SuccessResultPartnerLimit } from "./SuccessResultPartnerLimit"; +import { apiFetch } from "../../common/http"; export function PartnerLimits() { const partnerId = useAppSelector(state => state.demoIdentity.partnerId); @@ -22,7 +23,7 @@ export function PartnerLimits() { } const url = `/api/v1/partners/${encodeURIComponent(partnerId)}`; - const response = await fetch(url); + const response = await apiFetch(url); await sleep(500); diff --git a/frontend/src/components/private/PartnerProfile.tsx b/frontend/src/components/private/PartnerProfile.tsx index c87a93d..e246a0e 100644 --- a/frontend/src/components/private/PartnerProfile.tsx +++ b/frontend/src/components/private/PartnerProfile.tsx @@ -6,6 +6,7 @@ import type { UiState } from "../../common/types"; import { PartnerSchema, type PartnerDto } from "../public/zodType"; import { ResultBlock } from "../common/ResultBlock"; import { SuccessResultPartnerProfile } from "./SuccessResultPartnerProfile"; +import { apiFetch } from "../../common/http"; export function PartnerProfile() { const partnerId = useAppSelector(state => state.demoIdentity.partnerId); @@ -22,7 +23,7 @@ export function PartnerProfile() { } const url = `/api/v1/partners/${encodeURIComponent(partnerId)}`; - const response = await fetch(url); + const response = await apiFetch(url); await sleep(500); diff --git a/frontend/src/components/public/FetchApi.tsx b/frontend/src/components/public/FetchApi.tsx index 5b2ebc8..7edd45a 100644 --- a/frontend/src/components/public/FetchApi.tsx +++ b/frontend/src/components/public/FetchApi.tsx @@ -5,6 +5,7 @@ import { Title,Text, Stack, Button } from "@mantine/core"; import { sleep } from "../../common/tools"; import type { UiState } from "../../common/types"; import { SuccessResultCustomer, } from "./SuccessResultCustomer"; +import { apiFetch } from "../../common/http"; const idGood = "a3f767aa-1918-4b0d-a3c9-37e5a0e5f3b2"; const idBad = "a3f767aa-1918-4b0d-a3c9-37e5a0e5f3b3"; @@ -16,7 +17,7 @@ export function FetchApi() { setUiState({ kind: "loading" }); try { const urlGetCustomerById = `/api/v1/customers/${encodeURIComponent(id)}`; - const response = await fetch(urlGetCustomerById); + const response = await apiFetch(urlGetCustomerById); await sleep(500); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index d01d2cc..f015ea6 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -7,6 +7,8 @@ const target = process.env.API_URL || 'http://localhost:8091'; export default defineConfig({ plugins: [react()], server: { + host: "app.test.me", + port: 5173, proxy: { '/api': { target,