DEV Community

Rak
Rak

Posted on

Diving into CORS with Nitric in GO

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. We'll focus on the steps required to add the CORS middleware without going through the entire application.

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) {

}
Enter fullscreen mode Exit fullscreen mode

Creating the CORS Middleware Function

Below is the implementation of the CORS middleware function:

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)
}
Enter fullscreen mode Exit fullscreen mode

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

ctx.Response.Headers["Access-Control-Allow-Origin"] = []string{"*"}
Enter fullscreen mode Exit fullscreen mode

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.

ctx.Response.Headers["Access-Control-Allow-Origin"] = []string{"http://localhost:4001"}
Enter fullscreen mode Exit fullscreen mode

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.

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

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.

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

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.

Top comments (0)