Hummingbird and CORS
If you’ve stumbled upon this tutorial, you’ve likely seen a browser error that looks something like this:
Access to fetch at 'http://localhost:8080/api' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
CORS (Cross-Origin Resource Sharing) is a security feature that’s implemented by web browsers. It prevents malicious websites from making requests to other websites.
How does CORS work?
Before a browser makes the request to a server, it sends a preflight (OPTIONS) request to the server to ask for permission to make the request. The server then responds with a list of allowed origins, methods, and headers. If the browser’s request matches the server’s response, the browser will make the request.
While this is a great security feature, it’s often confusing the first time it blocks requests.
How to handle CORS in Hummingbird
Hummingbird has built-in support for CORS through CORSMiddleware
. Because CORSMiddleware is a RouterMiddleware
, it can be applies to all - or just a subset of routes.
router.add(middleware: CORSMiddleware())
hummingbird-and-cors.swift:5In the above example, the middleware is configured in its default configuration. This setup will allow all origins to make requests using a set of standard HTTP headers and methods.
This is a great starting point, and allows you to make most API requests. However, you may want to configure the middleware to be more restrictive or permissive.
Configuring the CORSMiddleware
The CORSMiddleware
initializer has a few parameters that you can use to configure it. The first one is the AllowOrigin
parameter.
There are three standard cases:
AllowOrigin.all
: Allows all origins to make requests.AllowOrigin.custom(_:)
: Allows requests from a specific origin.AllowOrigin.none
: Allows no origins to make requests.
This AllowOrigin
parameter is used to specify which origins are allowed to make requests.
The other variables are:
allowHeaders
, which specifies what headers are allowed to be sent with the request. This is an array ofHTTPField.Name
values.allowMethods
, specifying what HTTP methods are allowed to be used when making requests. This is an array ofHTTPRequest.Method
values.allowCredentials
, which specifies if users credentials (cookies, TLS client certificates, authorization headers, etc.) are allowed to be sent with the request. This is a boolean value.maxAge
, which specifies the maximum amount of time (in seconds) that the browser can cache the preflight response. This is aTimeAmount
value.
Example
Let’s look at an example of how to configure the middleware.
router.add(middleware: CORSMiddleware(
allowOrigin: .custom("http://example.com"),
allowHeaders: [.accept, .contentType],
allowMethods: [.get, .post],
allowCredentials: true,
maxAge: .seconds(3600))
)
hummingbird-and-cors.swift:9In the above example, the middleware is configured to allow requests from http://example.com
using the GET
and POST
methods. It allows the Accept
and Content-Type
headers and sets the maximum age of the preflight response to 1 hour.
Summary
CORS is a security feature that’s implemented by web browsers. It prevents malicious websites from making requests to other websites. Hummingbird has built-in support for CORS through CORSMiddleware
.
When you inevitably run into CORS errors, you now know how to configure CORSMiddleware
to allow requests from your frontends.
Related posts
Realtime MongoDB Updates with ChangeStreams and WebSockets
Learn how to implement real-time updates over WebSockets using ChangeStreams and MongoKitten
Beginner's Guide to Protocol Buffers and gRPC with Swift
Learn Protocol Buffers and gRPC with Swift in this easy, step-by-step beginner's guide.
Using Hummingbird's Request Contexts
Learn about request contexts in Hummingbird and how to use them.
How to Build a Proxy Server with Hummingbird
Learn how to leverage the flexibility and performance of Hummingbird to build a proxy server.
Getting Started with Hummingbird
Learn how to get started with Hummingbird 2, the modern Swift Web Framework.
Working with UDP in SwiftNIO
Create UDP servers and clients using SwiftNIO and structured concurrency