跳至主要内容
版本:v2.x

CORS

CORS(跨源资源共享)是 Fiber 的一个中间件,允许服务器指定谁可以访问其资源以及如何访问。它不是一个安全特性,而是一种放宽跨源请求的 Web 浏览器安全模型的方法。您可以在 Mozilla Developer Network 上了解有关 CORS 的更多信息。

此中间件通过向 Fiber 应用程序的响应中添加 CORS 头来工作。这些头指定哪些来源、方法和头允许跨源请求。它还处理预检请求,这是 CORS 机制,用于检查实际请求是否安全发送。

该中间件使用 AllowOrigins 选项来控制哪些来源可以进行跨源请求。它支持单个来源、多个来源、子域匹配和通配符来源。它还允许使用 AllowOriginsFunc 选项进行编程来源验证。

为了确保提供的 AllowOrigins 来源格式正确,此中间件会对其进行验证和规范化。它检查有效方案,即 HTTP 或 HTTPS,并将自动删除尾部斜杠。如果提供的来源无效,中间件将恐慌。

在配置 CORS 时,重要的是避免 常见陷阱,例如对凭据使用通配符来源、对来源过于宽松以及使用 AllowOriginsFunc 进行不充分的验证。错误配置可能会使您的应用程序面临各种安全风险。

签名

func New(config ...Config) fiber.Handler

示例

导入 Fiber Web 框架中包含的中间件包

import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
)

在启动 Fiber 应用程序后,您可以使用以下可能性

基本用法

要使用默认配置,只需使用 cors.New()。这将允许通配符来源“*”、所有方法、无凭据,并且没有头或公开头。

app.Use(cors.New())

自定义配置(特定来源、头等)

// Initialize default config
app.Use(cors.New())

// Or extend your config for customization
app.Use(cors.New(cors.Config{
AllowOrigins: "https://fiber.org.cn, https://gofiber.net",
AllowHeaders: "Origin, Content-Type, Accept",
}))

动态来源验证

您可以使用 AllowOriginsFunc 根据其来源以编程方式确定是否允许请求。当您需要根据数据库或其他动态来源验证来源时,这非常有用。如果允许来源,该函数应返回 true,否则返回 false

使用 AllowOriginsFunc 时,请务必查看 安全注意事项

注意

切勿允许 AllowOriginsFunc 对所有来源返回 true。当 AllowCredentials 设置为 true 时,这一点尤其重要。这样做可以绕过使用通配符来源和凭据的限制,使您的应用程序面临严重的安全性威胁。

如果您需要允许通配符来源,请使用带通配符 "*"AllowOrigins,而不是 AllowOriginsFunc

// dbCheckOrigin checks if the origin is in the list of allowed origins in the database.
func dbCheckOrigin(db *sql.DB, origin string) bool {
// Placeholder query - adjust according to your database schema and query needs
query := "SELECT COUNT(*) FROM allowed_origins WHERE origin = $1"

var count int
err := db.QueryRow(query, origin).Scan(&count)
if err != nil {
// Handle error (e.g., log it); for simplicity, we return false here
return false
}

return count > 0
}

// ...

app.Use(cors.New(cors.Config{
AllowOriginsFunc: func(origin string) bool {
return dbCheckOrigin(db, origin)
},
}))

禁止使用

以下示例被禁止,因为它会使您的应用程序面临安全风险。它将 AllowOrigins 设置为 "*"(通配符)并将 AllowCredentials 设置为 true

app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowCredentials: true,
}))

这将导致以下恐慌

panic: [CORS] 'AllowCredentials' is true, but 'AllowOrigins' cannot be set to `"*"`.

配置

属性类型描述默认值
下一步func(*fiber.Ctx) boolNext 定义了一个函数,当返回 true 时跳过此中间件。nil
AllowOriginsFuncfunc(origin string) boolAllowOriginsFunc 是一个函数,它根据请求的来源动态确定是否允许请求。如果此函数返回 true,则“Access-Control-Allow-Origin”响应头将设置为请求的“origin”头。仅当请求的来源与 AllowOrigins 中的任何来源不匹配时才使用此函数。nil
AllowOrigins字符串AllowOrigins 定义了一个逗号分隔的源列表,这些源可以访问资源。这支持子域匹配,因此你可以使用诸如“https://*.example.com”的值来允许 example.com 的任何子域提交请求。"*"
AllowMethods字符串AllowMethods 定义了访问资源时允许使用的方法列表。这是用来响应预检请求的。“GET,POST,HEAD,PUT,DELETE,PATCH”
AllowHeaders字符串AllowHeaders 定义了在进行实际请求时可以使用的请求头列表。这是用来响应预检请求的。""
AllowCredentials布尔值AllowCredentials 指示当凭据标志为 true 时是否可以公开对请求的响应。当用作对预检请求的响应的一部分时,这表示是否可以使用凭据进行实际请求。注意:如果为 true,则 AllowOrigins 不能设置为通配符 ("*") 以防止安全漏洞。false
ExposeHeaders字符串ExposeHeaders 定义了客户端允许访问的白名单头。""
MaxAge整数MaxAge 指示预检请求的结果可以缓存多长时间(以秒为单位)。如果你传递 MaxAge 0,则不会添加 Access-Control-Max-Age 头,并且浏览器默认使用 5 秒。要完全禁用缓存,请传递 MaxAge 值为负数。它将把 Access-Control-Max-Age 头设置为 0。0

默认配置

var ConfigDefault = Config{
Next: nil,
AllowOriginsFunc: nil,
AllowOrigins: "*",
AllowMethods: strings.Join([]string{
fiber.MethodGet,
fiber.MethodPost,
fiber.MethodHead,
fiber.MethodPut,
fiber.MethodDelete,
fiber.MethodPatch,
}, ","),
AllowHeaders: "",
AllowCredentials: false,
ExposeHeaders: "",
MaxAge: 0,
}

子域匹配

AllowOrigins 配置支持匹配任何级别的子域。这意味着你可以使用诸如 "https://*.example.com" 的值来允许 example.com 的任何子域提交请求,包括多个子域级别,例如 "https://sub.sub.example.com"

示例

如果你想允许来自 example.com 的任何子域(包括嵌套子域)的 CORS 请求,你可以像这样配置 AllowOrigins

app.Use(cors.New(cors.Config{
AllowOrigins: "https://*.example.com",
}))

工作原理

CORS 中间件通过向 Fiber 应用程序的响应中添加必要的 CORS 头来工作。这些头告诉浏览器哪些源、方法和头允许跨域请求。

当一个请求进来时,中间件首先检查它是否是一个预检请求,这是一个 CORS 机制,用于确定实际请求是否安全发送。预检请求是具有特定 CORS 头的 HTTP OPTIONS 请求。如果它是一个预检请求,则中间件会使用适当的 CORS 头响应并结束请求。

如果不是预检请求,则中间件会将 CORS 头添加到响应中并将请求传递到下一个处理程序。添加的实际 CORS 头取决于中间件的配置。

AllowOrigins 选项控制哪些源可以进行跨域请求。中间件处理不同的 AllowOrigins 配置如下

  • 单一来源:如果 AllowOrigins 设置为单一来源,例如 "http://www.example.com",并且该来源与传入请求的来源匹配,则中间件会将标头 Access-Control-Allow-Origin: http://www.example.com 添加到响应中。

  • 多个来源:如果 AllowOrigins 设置为多个来源,例如 "https://example.com, https://www.example.com",则中间件会选择与传入请求的来源匹配的来源。

  • 子域名匹配:如果 AllowOrigins 包含 "https://*.example.com",则会匹配 https://sub.example.com 等子域名,并且 "https://sub.example.com" 将成为标头。这也将匹配 https://sub.sub.example.com 等,但不会匹配 https://example.com

  • 通配符来源:如果 AllowOrigins 设置为 "*",则中间件会使用它并将标头 Access-Control-Allow-Origin: * 添加到响应中。

在以上所有情况下,除了通配符来源之外,中间件要么将 Access-Control-Allow-Origin 标头添加到与传入请求的来源匹配的响应中,要么根本不会添加该标头(如果来源不被允许)。

  • 以编程方式验证来源::中间件还处理 AllowOriginsFunc 选项,该选项允许您以编程方式确定是否允许某个来源。如果 AllowOriginsFunc 为某个来源返回 true,则中间件会将 Access-Control-Allow-Origin 标头设置为该来源。

AllowMethods 选项控制允许哪些 HTTP 方法。例如,如果 AllowMethods 设置为 "GET, POST",则中间件会将标头 Access-Control-Allow-Methods: GET, POST 添加到响应中。

AllowHeaders 选项指定实际请求中允许哪些标头。中间件将 Access-Control-Allow-Headers 响应标头设置为 AllowHeaders 的值。这会告知客户端它可以在实际请求中使用哪些标头。

AllowCredentials 选项指示是否可以在凭据标志为 true 时公开对请求的响应。如果 AllowCredentials 设置为 true,则中间件会将标头 Access-Control-Allow-Credentials: true 添加到响应中。为了防止安全漏洞,如果 AllowOrigins 设置为通配符 (*),则无法将 AllowCredentials 设置为 true

ExposeHeaders 选项定义了客户端允许访问的标头白名单。如果 ExposeHeaders 设置为 "X-Custom-Header",则中间件会将标头 Access-Control-Expose-Headers: X-Custom-Header 添加到响应中。

MaxAge 选项指示预检请求的结果可以缓存多长时间。如果 MaxAge 设置为 3600,则中间件会将标头 Access-Control-Max-Age: 3600 添加到响应中。

此中间件中使用 Vary 标头告知客户端服务器对请求的响应。对于预检请求和实际请求,Vary 标头都设置为 Access-Control-Request-MethodAccess-Control-Request-Headers。对于预检请求,Vary 标头还设置为 OriginVary 标头对于缓存非常重要。它帮助缓存(例如 Web 浏览器的缓存或 CDN)确定何时可以在响应未来请求时使用缓存的响应,以及何时需要向服务器查询新响应。

安全注意事项

配置 CORS 时,错误配置可能会让您的应用程序面临各种安全风险。以下是避免的一些安全配置和常见陷阱

安全配置

  • 指定允许的来源:不要使用通配符 ("*"),而应指定允许进行请求的确切域名。例如,AllowOrigins: "https://www.example.com, https://api.example.com" 确保只有这些域名可以向您的应用程序发出跨源请求。

  • 小心使用凭据:如果您的应用程序需要在跨源请求中支持凭据,请确保将 AllowCredentials 设置为 true,并在 AllowOrigins 中指定确切的来源。在这种情况下,不要使用通配符来源。

  • 限制公开的标头:仅通过适当设置 ExposeHeaders 将客户端应用程序必需的标头列入白名单。这可以最大程度地降低公开敏感信息的风险。

常见陷阱

  • 带有凭据的通配符来源:将 AllowOrigins 设置为 "*"(通配符)并将 AllowCredentials 设置为 true 是常见的错误配置。禁止这种组合,因为它会让您的应用程序面临安全风险。

  • 过于宽松的来源:指定过多的来源或使用过于宽泛的模式(例如,https://*.example.com)可能会无意中允许恶意网站与您的应用程序交互。在允许的来源方面尽可能具体。

  • 不充分的 AllowOriginsFunc 验证:在使用 AllowOriginsFunc 进行动态来源验证时,请确保该函数包含可靠的检查,以防止接受未经授权的来源。过于宽松的验证会导致安全漏洞。切勿允许 AllowOriginsFunc 对所有来源返回 true。当 AllowCredentials 设置为 true 时,这一点尤其重要。这样做会绕过使用带有凭据的通配符来源的限制,从而让您的应用程序面临严重的安全性威胁。如果您需要允许通配符来源,请使用带有通配符 "*"AllowOrigins,而不是 AllowOriginsFunc

请记住,安全 CORS 配置的关键在于具体性和谨慎。通过仔细选择允许哪些来源、方法和标头,您可以帮助保护您的应用程序免受跨源攻击。