CORS

The CORS (Cross-Origin Resource Sharing) mechanism allows a server to identify any origin other than its own so that browsers can access and load those resources. This mechanism is also used to check whether the server allows the browser to send a real request by sending a “precheck” request through the browser. In the “precheck” request header, there are HTTP methods and headers that the real request will use.

Hertz provides implementation of CORS middleware. The implementation here refers to GIN’s cors.

Install

go get github.com/hertz-contrib/cors

Example

package main

import (
    "time"

    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    // CORS for https://foo.com and https://github.com origins, allowing:
    // - PUT and PATCH methods
    // - Origin header
    // - Credentials share
    // - Preflight requests cached for 12 hours
    h.Use(cors.New(cors.Config{
        AllowOrigins:     []string{"https://foo.com"},
        AllowMethods:     []string{"PUT", "PATCH"},
        AllowHeaders:     []string{"Origin"},
        ExposeHeaders:    []string{"Content-Length"},
        AllowCredentials: true,
        AllowOriginFunc: func(origin string) bool {
            return origin == "https://github.com"
        },
        MaxAge: 12 * time.Hour,
    }))
    h.Spin()
}

Preflight request

For cross-origin access, in the case of a simple request, this is essentially adding an Origin field to the HTTP request header to describe where the source comes from, and the server can respond directly.

For non-simple cross-origin access requests (e.g. request method is PUT or PATCH, Content-Type field type is application/json, etc.), an HTTP preflight request is sent to verify that the client has access to the server before formal communication directly. A preflight request is a browser-initiated action that uses the HTTP Method OPTIONS.

Note: Some of the hertz-cors configurations will only take effect when a preflight request occurs.

Config

Hertz allows clients to access resources across origins through the use of cors middleware. You can finely control the extent to which server-side resources are allowed to be accessed across origins by customizing the configuration parameters of the Config structure. And you can also choose the default configuration of hertz-cors to allow clients from any origin to access resources.

Only part of the optional parameters are configured in the above Example, the full list of parameters for Config is as follows:

ParameterIntroduction
AllowAllOriginsThe property used to allow clients from any origin to access server-side resources, the default value is false
AllowOriginsThe property used to set the list of origins a cross-domain request can be executed from, the default value is []
AllowOriginFuncThe property used to set a custom function to validate the origin, if this option is set, the content of AllowOrigins is ignored
AllowMethodsThe property used to set the list of methods the client is allowed to use with cross-domain requests (takes effect when a preflight request is received)
AllowHeadersThe property used to set the list of non-simple headers the client is allowed to use with cross-domain requests, the default value is [] (takes effect when a preflight request is received)
AllowCredentialsThe property indicates whether the request can include user credentials like cookies, HTTP authentication, or client-side SSL certificates, the default value is false
ExposeHeadersThe property used to indicate which headers are safe to expose to the API of a CORS API specification, the default value is []
MaxAgeThe property used to set how long (in seconds) the results of a preflight request can be cached
AllowWildcardThe property used to allow to add of origins like http://some-domain/*, https://api.*, or http://some.*.subdomain.com, the default value is false
AllowBrowserExtensionsThe property used to allow usage of popular browser extensions schemas, the default value is false
AllowWebSocketsThe property used to allow usage of WebSocket protocol, the default value is false
AllowFilesThe property used to allow usage of file:// schema (dangerous!) use it only when you 100% sure it’s needed, the default value is false

AllowAllOrigins

If the property value is true, all cross-domain requests will be allowed.

Conflicts with AllowOriginFunc and AllowOrigins, only one of which can be configured at a time.

AllowOrigins

The property set a list of origins that can be accessed cross-domain, any cross-domain requests that satisfies the matching logic can access resource (only one * is allowed within each origin).

Conflicts with AllowAllOrigins and AllowOriginFunc, only one of which can be configured at a time.

If you want to use an origin with wildcards, the AllowWildcard parameter must also be set to true.

Sample Code1:

package main

import (
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    h.Use(cors.New(cors.Config{
        AllowOrigins:     []string{"https://foo.com"},
    }))
    h.Spin()
}

Sample Code2:

package main

import (
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    h.Use(cors.New(cors.Config{
        AllowWildcard: 	  true,
        AllowOrigins:     []string{"http://some-domain/*"},
    }))
    h.Spin()
}

AllowOriginFunc

It takes the origin as an argument and returns true if allowed or false otherwise.

Conflicts with AllowAllOrigins and AllowOrigins, only one of which can be configured at a time.

Function signatures:

func(origin string) bool

Sample Code:

package main

import (
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    h.Use(cors.New(cors.Config{
        AllowOriginFunc: func(origin string) bool {
            return origin == "https://github.com"
        },
    }))
    h.Spin()
}

AllowMethods

This configuration takes effect only when a preflight request is received and is used to set the list of HTTP methods the client is allowed to use with cross-domain requests.

If the request is a simple request initiated by GET or POST, no additional settings are required.

Sample Code:

package main

import (
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    h.Use(cors.New(cors.Config{
        AllowWildcard:    true,
        AllowMethods:     []string{"PUT", "PATCH"},
    }))
    h.Spin()
}

AllowHeaders

This configuration takes effect only when a preflight request is received. The Access-Control-Allow-Headers field is required if the browser request includes the Access-Control-Request-Headers field. It is a comma-separated string indicating all the header fields supported by the server.

Sample Code:

package main

import (
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    h.Use(cors.New(cors.Config{
        AllowHeaders:     []string{"Origin"},
    }))
    h.Spin()
}

ExposeHeaders

The property indicates which headers are safe to expose to the API of a CORS API specification.

Sample Code:

package main

import (
    "github.com/cloudwego/hertz/pkg/app/server"
    "github.com/hertz-contrib/cors"
)

func main() {
    h := server.Default()
    h.Use(cors.New(cors.Config{
        ExposeHeaders:    []string{"Content-Length"},
    }))
    h.Spin()
}

As for usage, you may refer to hertz cors


Last modified December 2, 2022 : chore: add lark footer link (#460) (f41a884)