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

CORS

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

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

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

为了确保提供的 AllowOrigins 源格式正确,这个中间件会验证并规范化它们。它会检查有效的方案,例如 HTTP 或 HTTPS,并且会自动移除尾部斜杠。如果提供的源无效,中间件将引发 panic。

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

签名

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

示例

导入属于 Fiber web 框架一部分的中间件包

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

在您初始化 Fiber app 后,您可以使用以下方式

基本用法

要使用默认配置,只需使用 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

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
AllowOriginsstringAllowOrigins 定义了一个逗号分隔的源列表,这些源可以访问资源。这支持子域匹配,因此您可以使用诸如 "https://*.example.com" 之类的值来允许 example.com 的任何子域提交请求。"*"
AllowMethodsstringAllowMethods 定义了一个允许访问资源时使用的方法列表。这用于响应预检请求。"GET,POST,HEAD,PUT,DELETE,PATCH"
AllowHeadersstringAllowHeaders 定义了一个请求头部列表,可在进行实际请求时使用。这用于响应预检请求。""
AllowCredentialsboolAllowCredentials 指示当凭据标志为 true 时,是否可以暴露对请求的响应。当作为预检请求响应的一部分使用时,这指示是否可以使用凭据进行实际请求。注意:如果设置为 true,AllowOrigins 不能设置为通配符 ("*"),以防止安全漏洞。false
ExposeHeadersstringExposeHeaders 定义了允许客户端访问的白名单头部。""
MaxAgeintMaxAge 指示预检请求的结果可以缓存多长时间(以秒为单位)。如果您传入 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 配置的关键在于具体性和谨慎性。通过仔细选择允许哪些源、方法和头部,您可以帮助保护您的应用程序免受跨域攻击。