ServerCORS

Cross-Origin Resource Sharing (CORS) in feTS

Cross-Origin Resource Sharing (CORS) is a mechanism that restricts web browsers from accessing resources outside their own domain. This becomes relevant when your API and web applications are deployed on different domains or subdomains.

Consider an example where your web client is deployed to example.com and your feTS server resides at api.example.com. Due to security constraints, the browser will prevent XHR requests to a domain other than the one currently displayed in the browser’s address bar.

To handle CORS issues, you have two main strategies:

  1. Proxy your requests: Setting up a proxy or redirect to forward requests from example.com/api/* to api.example.com will circumvent CORS issues entirely.

  2. Configure feTS to use CORS headers: feTS provides a CORS plugin that you can configure when creating the server. This can be done either by passing a CORSOptions object or a builder function that returns the CORSOptions object.

The CORSOptions can be configured as follows:

export type CORSOptions =
  | {
      origin?: string[] | string
      methods?: string[]
      allowedHeaders?: string[]
      exposedHeaders?: string[]
      credentials?: boolean
      maxAge?: number
    }
  | false

Here’s an example configuration using CORSOptions:

import { createRouter } from 'fets'
 
const router = createRouter({
  plugins: [
    useCORS({
      origin: 'http://localhost:4000',
      credentials: true,
      allowedHeaders: ['X-Custom-Header'],
      methods: ['POST']
    })
  ]
})

This configuration will return the following headers:

Access-Control-Allow-Origin: 'http://localhost:4000'
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: X-Custom-Header

Alternatively, you can use a builder function that takes your request and constructs the options:

import { createRouter } from 'fets'
 
const router = createRouter({
  plugins: [
    useCORS(request => {
      const requestOrigin = request.headers.get('origin')
      return {
        origin: requestOrigin,
        credentials: true,
        allowedHeaders: ['X-Custom-Header'],
        methods: ['POST']
      }
    })
  ]
})

This will return the same headers as the previous example, but will take the origin from the request and return it in the Access-Control-Allow-Origin header.

Default CORS Setting with the Plugin

By default, feTS will return Access-Control-Allow-Origin: \* when preflight requests are made. This allows cross-origin requests from browsers to work out of the box. However, it may be more secure to restrict access to a specific domain when deploying to production