Skip to content
Benyamin Khalife edited this page Dec 19, 2025 · 4 revisions

App Class Documentation

The App class is the core of the Webrium framework, providing essential functionality for application initialization, autoloading, environment management, localization, request handling, and comprehensive CORS security.

Table of Contents

Installation

The App class is the core of the Webrium framework and is automatically available.

use Webrium\App;

Basic Usage

require 'vendor/autoload.php';

use Webrium\App;

// Initialize application
App::initialize(__DIR__);

// Your application code here

// Run application
App::run();

Application Initialization

Initialize Framework

// Initialize with root directory
App::initialize(__DIR__);

This method:

  • Sets the application root path
  • Registers the autoloader
  • Loads helper functions
  • Enforces URL standards

Get Root Path

$rootPath = App::getRootPath();
// Returns: /var/www/html/myapp

Request Handling

Get Input Data

// Get all input data
$data = App::input();
// Works with: GET, POST, PUT, DELETE, JSON

// Get specific field
$username = App::input('username');

// With default value
$page = App::input('page', 1);

Supported Content Types:

  • GET parameters ($_GET)
  • POST form data ($_POST)
  • JSON payloads (automatically parsed)
  • PUT/DELETE request bodies

Return Data

// Return JSON
App::returnData(['status' => 'success', 'data' => $results]);

// With custom status code
App::returnData(['error' => 'Not found'], 404);

// Return plain text
App::returnData('Hello World');

Environment Variables

Load from .env File

Create a .env file in your project root:

APP_ENV=production
DB_HOST=localhost
DB_NAME=myapp
DB_USER=root
DB_PASS=secret
API_KEY=your-api-key-here
DEBUG=false

Access Environment Variables

// Get environment variable
$dbHost = App::env('DB_HOST');

// With default value
$debug = App::env('DEBUG', false);

// Check environment
if (App::env('APP_ENV') === 'production') {
    // Production-specific code
}

Supported Values:

  • true / false (converted to boolean)
  • null (converted to null)
  • Numbers (kept as strings or converted)
  • Quoted strings (quotes removed)

Localization

Set Application Locale

// Set locale
App::setLocale('en');
App::setLocale('fa');
App::setLocale('es');

Get Current Locale

$locale = App::getLocale();
// Returns: 'en'

// Check locale
if (App::isLocale('en')) {
    // English locale
}

Translation

Create language files in langs/{locale}/ directory:

langs/en/messages.php:

<?php
return [
    'welcome' => 'Welcome to our site',
    'hello_name' => 'Hello, :name!',
    'items_count' => 'You have :count items'
];

langs/fa/messages.php:

<?php
return [
    'welcome' => 'به سایت ما خوش آمدید',
    'hello_name' => 'سلام، :name!',
    'items_count' => 'شما :count مورد دارید'
];

Using Translations

// Simple translation
$text = App::trans('messages.welcome');
// Returns: "Welcome to our site"

// With replacements
$greeting = App::trans('messages.hello_name', ['name' => 'John']);
// Returns: "Hello, John!"

$count = App::trans('messages.items_count', ['count' => 5]);
// Returns: "You have 5 items"

CORS Management

Understanding CORS

Cross-Origin Resource Sharing (CORS) is a security mechanism that allows or restricts web applications running at one origin (domain) to access resources from a different origin.

What is an Origin?

An origin consists of:

  • Protocol (http/https)
  • Domain (example.com)
  • Port (80, 443, 8080, etc.)

Examples:

  • https://example.com ✓ Origin
  • https://app.example.com ✓ Different origin
  • https://example.com:8080 ✓ Different origin (different port)

Why CORS Matters

Without CORS, browsers block requests from:

Frontend: https://app.example.com
    ↓ (blocked by browser)
API: https://api.example.com

With proper CORS configuration:

Frontend: https://app.example.com
    ↓ (allowed)
API: https://api.example.com

Security Implications

⚠️ Security Risks

1. Open CORS (Wildcard *)

// ❌ DANGEROUS - Allows any website to access your API
App::corsMiddleware(['*']);

Risk: Any malicious website can make requests to your API, potentially stealing user data or performing unauthorized actions.

2. Credentials with Wildcard

// ❌ SECURITY VIOLATION - Will trigger error
App::corsMiddleware(['*'], [
    'allow_credentials' => true  // Cannot use with wildcard
]);

Risk: Browsers prohibit this combination as it would allow any site to make authenticated requests.

3. Overly Permissive Origins

// ❌ BAD - Too permissive
App::corsMiddleware([
    'http://localhost:3000',  // Development only
    'https://untrusted-site.com'  // Unknown third party
]);

✅ Secure CORS Configuration

1. Explicit Origin Whitelist

// ✓ GOOD - Explicit trusted origins only
App::corsMiddleware([
    'https://myapp.com',
    'https://admin.myapp.com',
    'https://mobile.myapp.com'
]);

2. Wildcard Subdomains (Careful Use)

// ✓ ACCEPTABLE - For your own subdomains
App::corsMiddleware([
    'https://*.myapp.com'  // Only your subdomains
]);

3. Environment-Based Configuration

// ✓ BEST - Different config per environment
$allowedOrigins = App::env('APP_ENV') === 'development'
    ? ['http://localhost:3000', 'http://localhost:8080']
    : ['https://myapp.com', 'https://admin.myapp.com'];

App::corsMiddleware($allowedOrigins);

Configuration Options

Basic Configuration

App::corsMiddleware([
    'https://example.com'
]);

Advanced Configuration

App::corsMiddleware([
    'https://example.com',
    'https://app.example.com'
], [
    'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
    'allowed_headers' => ['Content-Type', 'Authorization', 'X-Requested-With', 'Accept', 'Origin'],
    'allow_credentials' => true,  // Allow cookies/auth
    'max_age' => 86400,           // Cache preflight for 24 hours
    'expose_headers' => ['X-Total-Count', 'X-Page-Count']
]);

Configuration Options Explained

Option Type Default Description Security Impact
allowed_origins array [] List of allowed origin URLs HIGH - Controls who can access
allowed_methods array ['GET', 'POST', ...] HTTP methods allowed MEDIUM - Limit to needed methods only
allowed_headers array ['Content-Type', ...] Headers allowed in requests MEDIUM - Only allow necessary headers
allow_credentials bool false Allow cookies/authentication HIGH - Enable only for trusted origins
max_age int 86400 Preflight cache duration (seconds) LOW - Performance optimization
expose_headers array [] Headers exposed to client LOW - Allow client to read headers

Usage Scenarios

Scenario 1: Public API (No Authentication)

Use Case: Open API accessible from any website.

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;

App::initialize(__DIR__);

// ⚠️ Use with caution - only for truly public APIs
App::corsMiddleware(['*']);

Route::get('/api/public/data', function() {
    App::returnData([
        'data' => 'Public information',
        'timestamp' => time()
    ]);
});

App::run();

Security Considerations:

  • ✓ No sensitive data exposed
  • ✓ No authentication required
  • ✓ Rate limiting recommended
  • ✓ Input validation essential

Scenario 2: SPA (Single Page Application) with API

Use Case: React/Vue/Angular app on different domain/subdomain.

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;

App::initialize(__DIR__);

// Frontend on different domain
App::corsMiddleware([
    'https://app.mysite.com'
], [
    'allow_credentials' => true,  // Allow cookies for authentication
    'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
    'allowed_headers' => ['Content-Type', 'Authorization']
]);

Route::get('/api/user/profile', function() {
    // Check authentication
    $token = \Webrium\Header::getBearerToken();
    if (!$token) {
        App::returnData(['error' => 'Unauthorized'], 401);
    }
    
    // Return user data
    App::returnData(['user' => getUserData($token)]);
});

App::run();

Security Considerations:

  • ✓ Explicit origin whitelist
  • ✓ Authentication required
  • ✓ Credentials enabled only for trusted origin
  • ✓ Validate tokens on every request

Scenario 3: Multiple Frontend Applications

Use Case: Admin panel, mobile app, and public website sharing one API.

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;

App::initialize(__DIR__);

// Multiple trusted origins
App::corsMiddleware([
    'https://mysite.com',           // Public website
    'https://admin.mysite.com',     // Admin panel
    'https://mobile.mysite.com'     // Mobile app
], [
    'allow_credentials' => true,
    'allowed_headers' => [
        'Content-Type',
        'Authorization',
        'X-API-Key',          // Custom header for API key
        'X-Client-Version'     // Track client versions
    ],
    'expose_headers' => [
        'X-Total-Count',       // Pagination
        'X-Rate-Limit'         // Rate limit info
    ]
]);

// Different routes for different clients
Route::get('/api/public/articles', function() {
    // Public data - no auth needed
    App::returnData(getPublicArticles());
});

Route::get('/api/admin/users', function() {
    // Admin only - check role
    $token = \Webrium\Header::getBearerToken();
    if (!isAdmin($token)) {
        App::returnData(['error' => 'Forbidden'], 403);
    }
    App::returnData(getAllUsers());
});

App::run();

Security Considerations:

  • ✓ Each origin explicitly listed
  • ✓ Role-based access control
  • ✓ Different endpoints for different permissions
  • ✓ Client version tracking

Scenario 4: Development vs Production

Use Case: Different CORS settings for different environments.

<?php
require 'vendor/autoload.php';

use Webrium\App;

App::initialize(__DIR__);

// Environment-based CORS
$environment = App::env('APP_ENV', 'production');

if ($environment === 'development') {
    // Development - allow local origins
    App::corsMiddleware([
        'http://localhost:3000',      // React dev server
        'http://localhost:8080',      // Vue dev server
        'http://127.0.0.1:3000'       // Alternative localhost
    ], [
        'allow_credentials' => true
    ]);
} else {
    // Production - strict whitelist
    App::corsMiddleware([
        'https://mysite.com',
        'https://app.mysite.com'
    ], [
        'allow_credentials' => true,
        'max_age' => 86400            // Cache preflight for 24 hours
    ]);
}

App::run();

Security Considerations:

  • ✓ Separate configs for dev/prod
  • ✓ Never commit localhost origins to production
  • ✓ Use environment variables
  • ✓ Longer cache for production (better performance)

Scenario 5: Microservices Architecture

Use Case: Multiple backend services communicating.

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;

App::initialize(__DIR__);

// Allow other microservices
App::corsMiddleware([
    'https://auth-service.internal',
    'https://payment-service.internal',
    'https://notification-service.internal'
], [
    'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
    'allowed_headers' => [
        'Content-Type',
        'Authorization',
        'X-Service-Token'     // Service-to-service auth
    ]
]);

Route::post('/api/internal/process', function() {
    // Verify service token
    $serviceToken = \Webrium\Header::get('X-Service-Token');
    if (!verifyServiceToken($serviceToken)) {
        App::returnData(['error' => 'Unauthorized service'], 403);
    }
    
    // Process request
    App::returnData(['status' => 'processed']);
});

App::run();

Security Considerations:

  • ✓ Internal domains only
  • ✓ Service-to-service authentication
  • ✓ Network-level security (VPC/firewall)
  • ✓ Token rotation strategy

Scenario 6: Wildcard Subdomains

Use Case: SaaS application with customer subdomains.

<?php
require 'vendor/autoload.php';

use Webrium\App;

App::initialize(__DIR__);

// Allow all subdomains
App::corsMiddleware([
    'https://*.myapp.com'  // customer1.myapp.com, customer2.myapp.com, etc.
], [
    'allow_credentials' => true,
    'allowed_headers' => [
        'Content-Type',
        'Authorization',
        'X-Tenant-ID'         // Multi-tenancy
    ]
]);

Route::get('/api/tenant/data', function() {
    $tenantId = \Webrium\Header::get('X-Tenant-ID');
    
    // Validate tenant has access
    if (!validateTenantAccess($tenantId)) {
        App::returnData(['error' => 'Forbidden'], 403);
    }
    
    App::returnData(getTenantData($tenantId));
});

App::run();

Security Considerations:

  • ✓ Wildcard only for your own domain
  • ✓ Tenant isolation required
  • ✓ Validate tenant in every request
  • ✓ Log cross-tenant access attempts

Scenario 7: Mobile App + Web App

Use Case: Native mobile app and web application.

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;

App::initialize(__DIR__);

App::corsMiddleware([
    'https://myapp.com',              // Web app
    'https://app.myapp.com',          // PWA
    'capacitor://localhost',          // iOS Capacitor app
    'http://localhost',               // Android Capacitor app
    'ionic://localhost'               // Ionic app
], [
    'allow_credentials' => true,
    'allowed_headers' => [
        'Content-Type',
        'Authorization',
        'X-Device-ID',                // Device tracking
        'X-App-Version'               // App version
    ]
]);

Route::post('/api/mobile/login', function() {
    $deviceId = \Webrium\Header::get('X-Device-ID');
    $appVersion = \Webrium\Header::get('X-App-Version');
    
    // Check if app version is supported
    if (version_compare($appVersion, MIN_SUPPORTED_VERSION, '<')) {
        App::returnData([
            'error' => 'Please update your app',
            'min_version' => MIN_SUPPORTED_VERSION
        ], 426); // Upgrade Required
    }
    
    // Process login
    App::returnData(['token' => generateToken($deviceId)]);
});

App::run();

Security Considerations:

  • ✓ Include mobile-specific origins
  • ✓ Version checking
  • ✓ Device fingerprinting
  • ✓ Force updates for critical security patches

Best Practices

✅ DO's

  1. Use Explicit Whitelists in Production
// ✓ GOOD
App::corsMiddleware([
    'https://myapp.com',
    'https://admin.myapp.com'
]);
  1. Enable Credentials Only When Needed
// ✓ GOOD - Only for authenticated requests
App::corsMiddleware(['https://app.myapp.com'], [
    'allow_credentials' => true
]);
  1. Limit HTTP Methods
// ✓ GOOD - Only allow necessary methods
App::corsMiddleware(['https://app.myapp.com'], [
    'allowed_methods' => ['GET', 'POST']  // Not PUT, DELETE if not needed
]);
  1. Use Environment Variables
// ✓ GOOD
$origins = explode(',', App::env('CORS_ALLOWED_ORIGINS'));
App::corsMiddleware($origins);
  1. Validate on Every Request
// ✓ GOOD - Use corsMiddleware early
App::initialize(__DIR__);
App::corsMiddleware($origins);  // Before routing
App::run();
  1. Log Rejected Origins
// ✓ GOOD - Monitor suspicious activity
if (!App::isOriginAllowed(\Webrium\Url::origin())) {
    error_log('Blocked CORS request from: ' . \Webrium\Url::origin());
}

❌ DON'Ts

  1. Never Use Wildcard in Production (Unless Truly Public)
// ❌ BAD
App::corsMiddleware(['*']);
  1. Don't Enable Credentials with Wildcard
// ❌ WILL FAIL
App::corsMiddleware(['*'], [
    'allow_credentials' => true
]);
  1. Don't Include Development Origins in Production
// ❌ BAD - localhost in production
App::corsMiddleware([
    'https://myapp.com',
    'http://localhost:3000'  // Should not be in production
]);
  1. Don't Allow All Methods
// ❌ BAD - Unnecessary methods
App::corsMiddleware($origins, [
    'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD', 'TRACE']
]);
  1. Don't Trust Origin Header Blindly
// ❌ BAD - Still validate authentication
Route::post('/api/data', function() {
    // Even if origin is allowed, verify auth token
    $token = \Webrium\Header::getBearerToken();
    if (!$token) {
        App::returnData(['error' => 'Unauthorized'], 401);
    }
    // ...
});

CORS Methods Reference

Enable CORS (Simple)

// Basic usage
App::enableCors(['https://example.com']);

// With config
App::enableCors(['https://example.com'], [
    'allow_credentials' => true
]);

// Current domain only
App::enableCors();  // Allows current domain

CORS Middleware (Recommended)

// Enforce CORS with validation
App::corsMiddleware([
    'https://example.com',
    'https://app.example.com'
]);

// With config and custom error code
App::corsMiddleware($origins, [
    'allow_credentials' => true
], 403);

Configure CORS

// Advanced configuration
App::configureCors([
    'allowed_origins' => ['https://example.com'],
    'allowed_methods' => ['GET', 'POST'],
    'allowed_headers' => ['Content-Type'],
    'allow_credentials' => false,
    'max_age' => 3600,
    'expose_headers' => []
]);

Set Origins

// Set allowed origins
App::setCorsOrigins(['https://example.com']);

// Add origin
App::addCorsOrigin('https://new-domain.com');

Check Origin

// Check if origin is allowed
if (App::isOriginAllowed()) {
    // Origin is in whitelist
}

// Check specific origin
if (App::isOriginAllowed('https://example.com')) {
    // Specific origin allowed
}

Get Configuration

// Get allowed origins
$origins = App::getAllowedOrigins();

// Get full config
$config = App::getCorsConfig();

// Check if CORS is enabled
if (App::isCorsEnabled()) {
    // CORS is active
}

Caching

Disable Cache

// Disable browser caching
App::disableCache();

This sets:

  • Cache-Control: no-store, no-cache, must-revalidate, max-age=0
  • Pragma: no-cache

Useful for:

  • Dynamic content
  • Sensitive data
  • APIs with changing data

Complete Examples

Example 1: Complete REST API

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;
use Webrium\Header;

// Initialize
App::initialize(__DIR__);

// Set locale based on header
$locale = Header::get('Accept-Language', 'en');
App::setLocale(substr($locale, 0, 2));

// CORS for frontend
App::corsMiddleware([
    'https://myapp.com',
    'https://app.myapp.com'
], [
    'allow_credentials' => true,
    'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
    'expose_headers' => ['X-Total-Count']
]);

// Authentication middleware
Route::middleware(function() {
    $token = Header::getBearerToken();
    if (!$token) {
        App::returnData(['error' => 'Unauthorized'], 401);
    }
    // Validate token...
});

// Routes
Route::get('/api/users', function() {
    $page = App::input('page', 1);
    $users = getUsers($page);
    
    Header::set('X-Total-Count', $users['total']);
    App::returnData($users);
});

Route::post('/api/users', function() {
    $data = App::input();
    $user = createUser($data);
    App::returnData($user, 201);
});

Route::put('/api/users/:id', function($id) {
    $data = App::input();
    $user = updateUser($id, $data);
    App::returnData($user);
});

Route::delete('/api/users/:id', function($id) {
    deleteUser($id);
    App::returnData(['message' => 'Deleted'], 204);
});

App::run();

Example 2: Multi-tenant SaaS API

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;
use Webrium\Header;

App::initialize(__DIR__);

// Environment-based CORS
$environment = App::env('APP_ENV', 'production');
$origins = $environment === 'production'
    ? ['https://*.myapp.com']
    : ['http://localhost:3000'];

App::corsMiddleware($origins, [
    'allow_credentials' => true,
    'allowed_headers' => [
        'Content-Type',
        'Authorization',
        'X-Tenant-ID'
    ]
]);

// Tenant validation middleware
Route::middleware(function() {
    $tenantId = Header::get('X-Tenant-ID');
    if (!$tenantId) {
        App::returnData(['error' => 'Tenant ID required'], 400);
    }
    
    // Validate tenant exists and is active
    if (!isActiveTenant($tenantId)) {
        App::returnData(['error' => 'Invalid tenant'], 403);
    }
    
    // Store tenant context
    define('CURRENT_TENANT', $tenantId);
});

// Tenant-scoped routes
Route::get('/api/tenant/settings', function() {
    $settings = getTenantSettings(CURRENT_TENANT);
    App::returnData($settings);
});

Route::post('/api/tenant/data', function() {
    $data = App::input();
    $result = saveTenantData(CURRENT_TENANT, $data);
    App::returnData($result);
});

App::run();

Example 3: Public API with Rate Limiting

<?php
require 'vendor/autoload.php';

use Webrium\App;
use Webrium\Route;
use Webrium\Header;

App::initialize(__DIR__);

// Public API - open CORS
App::corsMiddleware(['*']);

// Rate limiting middleware
Route::middleware(function() {
    $apiKey = Header::getApiKey();
    $ip = \Webrium\Url::clientIp();
    
    $identifier = $apiKey ?? $ip;
    $limit = $apiKey ? 1000 : 100;  // Higher limit for API keys
    
    $remaining = checkRateLimit($identifier, $limit);
    
    Header::setMultiple([
        'X-Rate-Limit' => (string)$limit,
        'X-Rate-Limit-Remaining' => (string)$remaining,
        'X-Rate-Limit-Reset' => (string)(time() + 3600)
    ]);
    
    if ($remaining <= 0) {
        App::returnData([
            'error' => 'Rate limit exceeded',
            'retry_after' => 3600
        ], 429);
    }
});

// Public endpoints
Route::get('/api/public/data', function() {
    $data = getPublicData();
    
    // Cache for 5 minutes
    Header::cache(300);
    App::returnData($data);
});

App::run();

API Reference

Initialization Methods

Method Description
initialize($dir) Initialize framework with root directory
getRootPath() Get application root path
run() Start application (initialize debugging and routing)

Request Methods

Method Description
input($key, $default) Get request input data
returnData($data, $statusCode) Return response data

Environment Methods

Method Description
env($key, $default) Get environment variable

Localization Methods

Method Description
setLocale($locale) Set application locale
getLocale() Get current locale
isLocale($locale) Check if locale matches
trans($key, $replacements) Get translation

CORS Methods

Method Description
enableCors($origins, $config) Enable CORS with configuration
corsMiddleware($origins, $config, $errorCode) CORS middleware with validation
configureCors($config) Configure CORS settings
setCorsOrigins($origins) Set allowed origins
addCorsOrigin($origins) Add origin to whitelist
isOriginAllowed($origin) Check if origin is allowed
getAllowedOrigins() Get allowed origins list
getCorsConfig() Get CORS configuration
isCorsEnabled() Check if CORS is enabled

Cache Methods

Method Description
disableCache() Disable browser caching

Security Guidelines

General Security Checklist

  • Use explicit origin whitelists (no * in production)
  • Enable credentials only for trusted origins
  • Validate authentication on every request
  • Use HTTPS in production
  • Implement rate limiting
  • Log and monitor blocked requests
  • Use environment-based configuration
  • Validate and sanitize all input
  • Keep dependencies updated
  • Use security headers (Header::security())

CORS Security Checklist

  • Never use wildcard with credentials
  • List only trusted origins
  • Limit allowed HTTP methods
  • Restrict allowed headers
  • Use separate configs for dev/prod
  • Validate origin header server-side
  • Implement authentication even with CORS
  • Monitor and log rejected requests
  • Use network-level security (firewall)
  • Regular security audits

Common Security Mistakes

  1. Trusting CORS alone for security

    • ❌ CORS is not authentication
    • ✓ Always validate tokens/sessions
  2. Using wildcard in production

    • ❌ Opens API to all websites
    • ✓ Use explicit whitelist
  3. Forgetting about other attack vectors

    • ❌ Only focusing on CORS
    • ✓ Implement CSRF, XSS protection
  4. Not validating input

    • ❌ Trusting client data
    • ✓ Validate and sanitize all input

Testing CORS

Using cURL

# Test preflight request
curl -X OPTIONS http://api.example.com/endpoint \
  -H "Origin: https://app.example.com" \
  -H "Access-Control-Request-Method: POST" \
  -H "Access-Control-Request-Headers: Content-Type" \
  -v

# Test actual request
curl -X POST http://api.example.com/endpoint \
  -H "Origin: https://app.example.com" \
  -H "Content-Type: application/json" \
  -d '{"test":"data"}' \
  -v

Using JavaScript

// Test from browser console
fetch('https://api.example.com/endpoint', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    credentials: 'include',  // If credentials enabled
    body: JSON.stringify({test: 'data'})
})
.then(response => response.json())
.then(data => console.log('Success:', data))
.catch(error => console.error('CORS Error:', error));

Troubleshooting

Common CORS Errors

1. "No 'Access-Control-Allow-Origin' header is present"

  • Cause: CORS not configured or origin not whitelisted
  • Fix: Add origin to corsMiddleware()

2. "Credential is not supported if the CORS header 'Access-Control-Allow-Origin' is '*'"

  • Cause: Using wildcard with credentials
  • Fix: Use explicit origins with credentials

3. "Method DELETE is not allowed by Access-Control-Allow-Methods"

  • Cause: Method not in allowed list
  • Fix: Add method to allowed_methods config

4. "Request header field Authorization is not allowed"

  • Cause: Header not in allowed list
  • Fix: Add header to allowed_headers config

Clone this wiki locally