登录 注册

 golang在子域名与子域名之间,如何共享cookie

2025-09-29  回复(0) 

在 Golang 中,要实现子域名与子域名之间共享 Cookie,核心在于 设置 Cookie 的 Domain 属性

当你在一个子域名(例如 app1.example.com)上设置 Cookie 时,如果你希望另一个子域名(例如 app2.example.com)也能访问到这个 Cookie,你需要将 Cookie 的 Domain 设置为 父域名

核心概念:Domain 属性

Cookie 的 Domain 属性指定了哪个域名能够接收或发送这个 Cookie。

* .example.com: 如果你设置 Domain.example.com,那么 example.com 的所有子域名(包括 www.example.com, app1.example.com, app2.example.com 等)都可以访问和发送这个 Cookie。
* app1.example.com: 如果你设置 Domainapp1.example.com,那么只有 app1.example.com 及其子域名(如果存在)能够访问和发送这个 Cookie。其他子域名(如 app2.example.com)将无法访问。

Golang 实现步骤

1. 创建 Cookie: 使用 http.Cookie 结构体来创建 Cookie。
2. 设置 Domain 属性: 将 Domain 属性设置为你希望共享的父域名,例如 .yourdomain.com
3. 设置 Path 属性: 通常,将 Path 设置为 / 是为了让 Cookie 在整个域下都可用。
4. 设置 ExpiresMax-Age: 设置 Cookie 的过期时间,决定其生命周期。
5. 发送 Cookie: 使用 http.SetCookie 函数将 Cookie 添加到 HTTP 响应头中。

示例代码

假设我们有两个子域名:app1.example.comapp2.example.com。我们希望在 app1.example.com 上设置一个 Cookie,让 app2.example.com 也能读取到。

场景 1:在 app1.example.com 上设置共享 Cookie

go
package main

import (
"fmt"
"net/http"
"time"
)

func setCookieHandler(w http.ResponseWriter, r *http.Request) {
// 创建一个Cookie
cookie := &http.Cookie{
Name: "shared_session_id",
Value: "user123_session_abc",
Path: "/", // 覆盖整个域名
Domain: ".example.com", // **设置为父域名,以实现子域名共享**
Expires: time.Now().Add(24 * time.Hour), // 24小时后过期
HttpOnly: true, // 仅可通过HTTP访问,防止XSS攻击
Secure: true, // 仅通过HTTPS发送
SameSite: http.SameSiteLaxMode, // 考虑SameSite属性
}

// 将Cookie添加到响应头
http.SetCookie(w, cookie)
fmt.Fprintf(w, "Cookie 'shared_session_id' set successfully for .example.com")
}

func main() {
http.HandleFunc("/set-cookie", setCookieHandler)

fmt.Println("Server starting on :8080 (for app1.example.com)")
// 假设这个服务器运行在 app1.example.com
// 在实际部署中,你需要配置DNS和Web服务器来指向正确的域名和端口
// 例如:
// 1. 配置 hosts 文件:
// 127.0.0.1 app1.example.com app2.example.com
// 2. 运行 Golang server
// 3. 使用反向代理 (如 Nginx) 来区分 app1 和 app2 的请求,并将它们路由到同一个 Golang server,或者不同的 Golang server。
// 如果两个子域名指向同一个 Golang server,则可以直接运行此代码。
// 如果指向不同的 Golang server,那么需要在各自的 server 中实现读取Cookie的逻辑。
err := http.ListenAndServe(":8080", nil)
if err != nil {
panic(err)
}
}


场景 2:在 app2.example.com 上读取共享 Cookie

go
package main

import (
"fmt"
"net/http"
)

func getCookieHandler(w http.ResponseWriter, r *http.Request) {
// 从请求中查找Cookie
cookie, err := r.Cookie("shared_session_id")
if err != nil {
if err == http.ErrNoCookie {
fmt.Fprintf(w, "Cookie 'shared_session_id' not found")
} else {
fmt.Fprintf(w, "Error getting cookie: %v", err)
}
return
}

// 如果找到Cookie,则打印其值
fmt.Fprintf(w, "Found shared_session_id: %s", cookie.Value)
}

func main() {
http.HandleFunc("/get-cookie", getCookieHandler)

fmt.Println("Server starting on :8081 (for app2.example.com)")
// 假设这个服务器运行在 app2.example.com
// 同样需要配置 hosts 文件和/或反向代理
err := http.ListenAndServe(":8081", nil)
if err != nil {
panic(err)
}
}


如何测试

1. 配置 hosts 文件: 在你的本地机器上修改 hosts 文件(Linux/macOS: /etc/hosts, Windows: C:\Windows\System32\drivers\etc\hosts)添加如下内容:

127.0.0.1 app1.example.com app2.example.com

这会将 app1.example.comapp2.example.com 解析到本地回环地址 127.0.0.1

2. 运行 Golang 服务器:
* 选项 A: 单个 Golang 服务器,使用反向代理:
* 运行上面 setCookieHandler 的代码(监听 :8080)。
* 运行上面 getCookieHandler 的代码(监听 :8081)。
* 配置一个反向代理(如 Nginx),将 app1.example.com 的请求转发到 :8080,将 app2.example.com 的请求转发到 :8081
* 选项 B: 单个 Golang 服务器,使用不同的端口 (模拟):
* 运行上面 setCookieHandler 的代码(监听 :8080)。
* 修改 getCookieHandlermain 函数,让它也监听 :8080
* 然后,在浏览器中访问 http://app1.example.com:8080/set-cookie,再访问 http://app2.example.com:8080/get-cookie。 这种方式更直接地模拟了不同子域名发送到同一个服务器的情况。

3. 浏览器测试:
* 在浏览器中访问 http://app1.example.com:8080/set-cookie (或相应的地址)。
* 然后,在同一个浏览器中访问 http://app2.example.com:8080/get-cookie (或相应的地址)。
* 如果设置成功,你应该在 app2.example.com 的页面上看到 “Found shared_session_id: user123_session_abc”。

重要注意事项:

* Domain 属性必须是父域名: 例如,如果你的子域名是 sub1.sub2.example.comsub3.example.com,并且你想让它们共享 Cookie,那么你设置的 Domain 必须是 .example.com
* . 开头: Domain 属性通常需要以 . 开头,表示这是一个顶级域名(或第二级域名),并且允许其所有子域名访问。
* Secure 属性: 在生产环境中,强烈建议将 Secure 属性设置为 true,这意味着 Cookie 只会在 HTTPS 连接上传输,以提高安全性。
* HttpOnly 属性: 同样建议设置为 true,以防止客户端 JavaScript 访问 Cookie,从而降低 XSS 攻击的风险。
* SameSite 属性: SameSite 属性是用于控制 Cookie 在跨站请求中的发送方式,是现代 Web 安全的重要组成部分。http.SameSiteLaxMode 通常是一个不错的默认选择。
* DNS 和 Web 服务器配置: 上述示例代码假定你已经正确配置了 DNS 和 Web 服务器,使得 app1.example.comapp2.example.com 能够被访问到,并且流量被路由到你的 Golang 服务器。在实际部署中,这可能涉及 Nginx、Apache 等反向代理。
* 端口: 在本地测试时,使用不同的端口(如 :8080:8081)可以帮助区分不同的服务器实例。在生产环境中,通常会将子域名指向同一个(或一组)Web 服务器,由 Web 服务器将请求路由到不同的应用程序或处理逻辑。
* 同一协议: Cookie 的共享也需要遵循协议。如果一个子域名使用 HTTPS,而另一个使用 HTTP,那么 Secure 属性会阻止 Cookie 的跨协议共享(这是预期的行为)。

通过正确设置 Cookie 的 Domain 属性为父域名,Golang 可以轻松实现子域名之间的 Cookie 共享。

#回复 AI问答 上传/拍照 我的