Diving into CORS with Nitric in GO
Tags: go, tutorial, cloudcomputing, productivity
Published: 2023-10-17 02:47:47

**Understanding CORS Middleware in Web Applications**

CORS, or Cross-Origin Resource Sharing, is a crucial security feature implemented by web browsers. It allows or restricts web applications running on one domain from making requests for resources hosted on a different domain. This concept is fundamental for web applications that need to handle cross-origin requests.

To illustrate how to implement an HTTP server with CORS middleware, let's use the application we built in our [profiles application guide](https://dev.to/rsiv/your-first-api-with-go-nitric-39b7). We'll focus on the steps required to add the CORS middleware without going through the entire application.

```go
package main

import (
  "fmt"
  "github.com/nitrictech/go-sdk/nitric"
)

func main() {
  // Update to reference the middleware function named cors
  profilesApi, err := nitric.NewApi("public", nitric.WithMiddleware(cors))
  if err != nil {
    return
  }

  // Continue with the rest of the profiles API setup here.
}

// TODO: Implement the cors middleware function
func cors(ctx *faas.HttpContext, next faas.HttpHandler) (*faas.HttpContext, error) {
        
}
```

## Creating the CORS Middleware Function

Below is the implementation of the CORS middleware function:

```go
func cors(ctx *faas.HttpContext, next faas.HttpHandler) (*faas.HttpContext, error) {
  headers := ctx.Request.Headers()

  // Allow all Origins
  ctx.Response.Headers["Access-Control-Allow-Origin"] = []string{"*"}

  // Allow local development only (i.e., localhost)
  ctx.Response.Headers["Access-Control-Allow-Origin"] = []string{"http://localhost:4001"}

  ctx.Response.Headers["Access-Control-Allow-Methods"] = []string{"GET, POST, PATCH, DELETE, OPTIONS"}

  if headers["Access-Control-Request-Headers"] != nil {
    ctx.Response.Headers["Access-Control-Allow-Methods"] = headers["Access-Control-Request-Headers"]
  }

  return next(ctx)
}
```

Now, let's break down what each part of the CORS middleware function does:

```go
ctx.Response.Headers["Access-Control-Allow-Origin"] = []string{"*"}
```

This line sets the `Access-Control-Allow-Origin` header in the response, allowing requests from any origin (*). It's a permissive setting that permits any domain to access your resources.

```go
ctx.Response.Headers["Access-Control-Allow-Origin"] = []string{"http://localhost:4001"}
```

This line adds an additional `Access-Control-Allow-Origin` header, specifically permitting requests from `http://localhost:4001`. This is particularly useful during local development when you want to test your application from a local server.

```go
ctx.Response.Headers["Access-Control-Allow-Methods"] = []string{"GET, POST, PATCH, DELETE, OPTIONS"}
```

This line sets the `Access-Control-Allow-Methods` header to specify which HTTP methods are allowed for cross-origin requests. In this case, it allows `GET`, `POST`, `PATCH`, `DELETE`, and `OPTIONS` methods.

```go
if headers["Access-Control-Request-Headers"] != nil {
  ctx.Response.Headers["Access-Control-Allow-Methods"] = headers["Access-Control-Request-Headers"]
}
```

This conditional statement checks if the incoming request includes an `Access-Control-Request-Headers` header, which specifies the headers that the client wants to send in the actual request. If this header is present, your code sets the `Access-Control-Allow-Methods` header to match the requested headers, effectively allowing the requested custom headers to be sent in the cross-origin request.

With this CORS middleware in place, your web application will be better equipped to handle cross-origin requests securely and efficiently.