作者 青鸟

之前在做前后端分离的项目的时候,前后端的鉴权方式选择了session,在这个过程中遇到了浏览器的同源策略的问题,也是在查阅了好多资料后,使用了跨域资源共享,完成了鉴权,因此写一篇博客来记录一下。

什么是同源策略

同源策略(Same-Origin Policy)是一种安全性措施,用于Web浏览器中,以防止不同源(不同域、不同协议或不同端口)的网页之间在浏览器中的JavaScript代码之间进行未经授权的交互。同源策略的目标是保护用户的隐私和安全,防止恶意网站通过恶意脚本访问其他网站的数据或执行潜在的恶意操作。

同源策略的主要规则包括:

  1. 协议相同:网页必须使用相同的协议(通常是http://或https://)才能被认为是同源的。

  2. 域名相同:网页必须具有相同的主机名(域名),例如,www.example.com 和 sub.example.com 不被视为同源。

  3. 端口相同:网页必须在相同的端口上运行,否则会被视为不同源。例如,http://example.com:80http://example.com:8080 是不同源的。

同源策略的主要影响包括:

  • 防止跨站点脚本攻击(XSS):通过禁止不同源网页的脚本相互访问,可以减少XSS攻击的风险,因为攻击者无法轻易注入恶意脚本并访问其他源的数据。

  • 防止跨站请求伪造(CSRF):同源策略帮助防止CSRF攻击,因为攻击者无法在不同源的网页上执行未经授权的操作。

  • 增强隐私:同源策略防止网页从不同源获取敏感信息,提高了用户的隐私保护。

然而,有些情况下需要跨源通信,例如通过跨源资源共享(CORS)机制来授权访问其他源的数据。CORS允许服务器明确指定哪些源可以访问其资源,从而在一定程度上绕过同源策略的限制。这使得跨源交互在需要时仍然安全可控。

什么是跨域资源共享

跨域资源共享(Cross-Origin Resource Sharing,简称CORS)是一种机制,允许Web服务器在响应中告知浏览器是否允许来自不同源(不同域、协议或端口)的网页访问其资源。CORS通过HTTP标头来实现,提供了一种安全的方法,以便服务器授权其他源的浏览器请求。

以下是CORS的主要工作原理:

  1. 浏览器发出跨源请求

    • 当浏览器中的网页尝试从不同源的服务器请求资源(例如,通过XMLHttpRequest或Fetch API),浏览器会首先发送一个跨源请求。
  2. 服务器响应

    • 服务器收到请求后,可以在响应中包含CORS相关的HTTP标头,以指示是否允许来自特定源的请求。
    • 主要的CORS标头包括:
      • Access-Control-Allow-Origin:指定哪些源被允许访问资源。可以是具体的源或通配符(*),表示允许所有源访问。
      • Access-Control-Allow-Methods:指定允许的HTTP方法,例如GET、POST、PUT等。
      • Access-Control-Allow-Headers:指定允许的自定义HTTP标头。
      • Access-Control-Allow-Credentials:指定是否允许浏览器发送凭据(如Cookie或HTTP认证)。
      • Access-Control-Expose-Headers:指定哪些响应标头可以在浏览器中访问。
  3. 浏览器处理响应

    • 浏览器会检查服务器响应的CORS标头,以确定是否允许跨源请求。
    • 如果服务器允许请求,浏览器将允许网页访问响应的资源,并将响应交给JavaScript代码处理。
    • 如果服务器不允许请求,浏览器会阻止JavaScript代码访问响应的资源,并在控制台中报告CORS错误。

CORS允许服务器细粒度地控制哪些源可以访问其资源,从而提供了一种安全的跨域通信机制。这对于Web应用程序与第三方API、跨域Ajax请求以及单页应用程序等情况非常有用。同时,CORS也有助于保护用户数据和安全,因为它不会简单地允许所有源访问资源。服务器必须明确配置CORS规则,以确保只有授权的源能够访问其资源。

Gin实现跨域资源共享

1
2
3
4
5
6
7
func GetCors() gin.HandlerFunc {
corsConfig := cors.DefaultConfig()
corsConfig.AllowOrigins = []string{config.Config.GetString("allow_origins")}
corsConfig.AllowCredentials = true
corsConfig.AddAllowMethods("OPTIONS")
return cors.New(corsConfig)
}

然后在main.go中只需要引入即可

1
r.Use(corsConfig.GetCors())

最后在yaml中配置即可

1
allow_origins: http://127.0.0.1:5173

参考文章:

跨域资源共享 CORS 详解

浏览器同源政策及其规避方法

浏览器的同源策略