Skip to content

pndlm/jub0bs-cors

 
 

Repository files navigation

jub0bs/cors

Go Reference license build codecov goreport

A principled CORS middleware library for Go, designed to be both easier to use and harder to misuse than existing alternatives.

About CORS

The Same-Origin Policy (SOP) is a security mechanism that Web browsers implement to protect their users. In particular, the SOP places some restrictions on cross-origin network access, in terms of both sending and reading. Cross-Origin Resource Sharing (CORS) is a protocol that lets servers instruct browsers to relax those restrictions for select clients.

This package allows you to configure and build net/http middleware that implement CORS.

Installation

go get github.com/jub0bs/cors

jub0bs/cors requires Go 1.22 or above.

Example

The following program demonstrates how to create a CORS middleware that

  • allows anonymous access from Web origin https://example.com,
  • with requests whose method is either GET or POST, and
  • (optionally) with request header Authorization,

and how to apply the middleware in question to all the resources accessible under some /api/ path:

package main

import (
  "io"
  "log"
  "net/http"

  "github.com/jub0bs/cors"
)

func main() {
  mux := http.NewServeMux()
  mux.HandleFunc("GET /hello", handleHello) // note: not configured for CORS

  // create CORS middleware
  corsMw, err := cors.NewMiddleware(cors.Config{
    Origins:        []string{"https://example.com"},
    Methods:        []string{http.MethodGet, http.MethodPost},
    RequestHeaders: []string{"Authorization"},
  })
  if err != nil {
    log.Fatal(err)
  }
  corsMw.SetDebug(true) // turn debug mode on (optional)

  api := http.NewServeMux()
  api.HandleFunc("GET /users", handleUsersGet)
  api.HandleFunc("POST /users", handleUsersPost)
  mux.Handle("/api/", http.StripPrefix("/api", corsMw.Wrap(api))) // note: method-less pattern here

  log.Fatal(http.ListenAndServe(":8080", mux))
}

func handleHello(w http.ResponseWriter, _ *http.Request) {
  io.WriteString(w, "Hello, World!")
}

func handleUsersGet(w http.ResponseWriter, _ *http.Request) {
  // omitted
}

func handleUsersPost(w http.ResponseWriter, _ *http.Request) {
  // omitted
}

Try it out yourself by saving this program to a file named server.go. You may need to adjust the port number if port 8080 happens to be unavailable on your machine. Then build and run your server:

go build server.go
./server

If no error occurred, the server is now running on localhost:8080 and the various resources accessible under the /api/ path are now configured for CORS as desired.

Documentation

The documentation is available on pkg.go.dev.

Moreover, guidance on how to use jub0bs/cors with popular third-party routers can be found in jub0bs/cors-examples.

Code coverage

coverage

Benchmarks

Some benchmarks pitting jub0bs/cors against rs/cors are available in jub0bs/cors-benchmarks.

License

All source code is covered by the MIT License.

Additional resources

Reasons for favoring rs/cors over jub0bs/cors

Despite all of jub0bs/cors's goodness, you may still have valid reasons for sticking with rs/cors, at least for the time being. Here is as exhaustive a list as I could come up with: