Skip to content

Latest commit

 

History

History
151 lines (112 loc) · 4.99 KB

README.md

File metadata and controls

151 lines (112 loc) · 4.99 KB

jub0bs/fcors

Go Reference license build codecov goreport

An experimental CORS middleware library for Go.

Unless you're a big fan of functional options, you should use github.com/jub0bs/cors instead.

About CORS

The Same-Origin Policy (SOP) is a security mechanism that Web browsers implement to protect their users. In particular, the SOP restricts 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.

jub0bs/fcors allows you to configure and build net/http middleware that implement CORS.

Design philosophy

jub0bs/fcors is designed to be both easier to use and harder to misuse than other CORS middleware libraries; see Fearless CORS: a design philosophy for CORS middleware libraries (and a Go implementation) and Useful Functional-Options Tricks for Better Libraries (GopherCon Europe 2023).

Praise for jub0bs/fcors

I really like the declarative API. It lets you say what behavior you want rather than setting specific headers. It means that, as a user, you don’t have to relearn the nuances of CORS every time you want to make a change.

Paul Carleton (Staff Software Engineer at Stripe)

Installation

go get github.com/jub0bs/fcors

jub0bs/fcors requires Go 1.21 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/fcors"
)

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

  // create CORS middleware
  cors, err := fcors.AllowAccess(
    fcors.FromOrigins("https://example.com"),
    fcors.WithMethods(http.MethodGet, http.MethodPost),
    fcors.WithRequestHeaders("Authorization"),
  )
  if err != nil {
    log.Fatal(err)
  }

  api := http.NewServeMux()
  api.HandleFunc("GET /users", handleUsersGet)
  api.HandleFunc("POST /users", handleUsersPost)
  mux.Handle("/api/", http.StripPrefix("/api", cors(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.

Code coverage

coverage

License

All source code is covered by the MIT License.