Cookie与Session #
一、Cookie基础 #
1.1 什么是Cookie #
Cookie是存储在客户端的小型数据,用于在HTTP请求之间保持状态。
1.2 Cookie属性 #
| 属性 | 说明 |
|---|---|
| Name | Cookie名称 |
| Value | Cookie值 |
| Path | 有效路径 |
| Domain | 有效域名 |
| Expires | 过期时间 |
| MaxAge | 最大存活时间(秒) |
| Secure | 仅HTTPS传输 |
| HTTPOnly | 禁止JavaScript访问 |
| SameSite | 跨站策略 |
二、Cookie操作 #
2.1 获取Cookie #
go
app.Get("/get-cookie", func(c *fiber.Ctx) error {
// 获取单个Cookie
session := c.Cookies("session")
token := c.Cookies("token", "default")
return c.JSON(fiber.Map{
"session": session,
"token": token,
})
})
2.2 设置Cookie #
go
app.Get("/set-cookie", func(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "session",
Value: "abc123",
Expires: time.Now().Add(24 * time.Hour),
HTTPOnly: true,
Secure: true,
SameSite: "Lax",
})
return c.SendString("Cookie set")
})
2.3 Cookie完整配置 #
go
app.Get("/full-cookie", func(c *fiber.Ctx) error {
c.Cookie(&fiber.Cookie{
Name: "user",
Value: "john",
Path: "/",
Domain: "example.com",
Expires: time.Now().Add(24 * time.Hour),
MaxAge: 86400,
Secure: true,
HTTPOnly: true,
SameSite: "Strict",
SessionOnly: false,
})
return c.SendString("Full cookie set")
})
2.4 删除Cookie #
go
app.Get("/clear-cookie", func(c *fiber.Ctx) error {
c.ClearCookie("session")
return c.SendString("Cookie cleared")
})
// 删除多个Cookie
app.Get("/clear-cookies", func(c *fiber.Ctx) error {
c.ClearCookie("session", "token", "user")
return c.SendString("Cookies cleared")
})
2.5 Cookie安全配置 #
go
func SetSecureCookie(c *fiber.Ctx, name, value string, maxAge int) {
c.Cookie(&fiber.Cookie{
Name: name,
Value: value,
MaxAge: maxAge,
Secure: true, // 仅HTTPS
HTTPOnly: true, // 禁止JS访问
SameSite: "Strict", // 严格同源
Path: "/",
})
}
app.Get("/secure-cookie", func(c *fiber.Ctx) error {
SetSecureCookie(c, "auth_token", "xyz789", 3600)
return c.SendString("Secure cookie set")
})
三、Session管理 #
3.1 什么是Session #
Session是存储在服务器端的会话数据,通过Session ID与客户端关联。
3.2 内存Session #
go
package main
import (
"sync"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/session"
)
var store = session.New()
func main() {
app := fiber.New()
app.Get("/login", func(c *fiber.Ctx) error {
// 获取Session
sess, err := store.Get(c)
if err != nil {
return err
}
// 设置Session数据
sess.Set("user_id", 123)
sess.Set("username", "john")
// 保存Session
if err := sess.Save(); err != nil {
return err
}
return c.SendString("Logged in")
})
app.Get("/profile", func(c *fiber.Ctx) error {
sess, err := store.Get(c)
if err != nil {
return err
}
userID := sess.Get("user_id")
username := sess.Get("username")
if userID == nil {
return c.Status(401).SendString("Not logged in")
}
return c.JSON(fiber.Map{
"user_id": userID,
"username": username,
})
})
app.Get("/logout", func(c *fiber.Ctx) error {
sess, err := store.Get(c)
if err != nil {
return err
}
// 销毁Session
if err := sess.Destroy(); err != nil {
return err
}
return c.SendString("Logged out")
})
app.Listen(":3000")
}
3.3 Session配置 #
go
var store = session.New(session.Config{
// Session过期时间
Expiration: 24 * time.Hour,
// Cookie名称
KeyLookup: "cookie:session_id",
// Cookie配置
Cookie: fiber.Cookie{
Secure: true,
HTTPOnly: true,
SameSite: "Lax",
},
// Key生成器
KeyGenerator: func() string {
return uuid.New().String()
},
})
3.4 Redis Session存储 #
go
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/session"
"github.com/gofiber/storage/redis"
)
func main() {
// Redis存储
storage := redis.New(redis.Config{
Host: "localhost",
Port: 6379,
Password: "",
Database: 0,
})
// Session存储
store := session.New(session.Config{
Storage: storage,
Expiration: 24 * time.Hour,
})
app := fiber.New()
app.Get("/login", func(c *fiber.Ctx) error {
sess, err := store.Get(c)
if err != nil {
return err
}
sess.Set("user_id", 123)
sess.Save()
return c.SendString("Logged in")
})
app.Listen(":3000")
}
四、Session中间件 #
4.1 认证中间件 #
go
func AuthRequired(store *session.Store) fiber.Handler {
return func(c *fiber.Ctx) error {
sess, err := store.Get(c)
if err != nil {
return c.Status(500).SendString("Session error")
}
userID := sess.Get("user_id")
if userID == nil {
return c.Status(401).JSON(fiber.Map{
"error": "Unauthorized",
})
}
c.Locals("user_id", userID)
return c.Next()
}
}
// 使用
app.Get("/protected", AuthRequired(store), func(c *fiber.Ctx) error {
userID := c.Locals("user_id")
return c.JSON(fiber.Map{"user_id": userID})
})
4.2 完整认证示例 #
go
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/session"
)
var store = session.New()
func main() {
app := fiber.New()
// 登录
app.Post("/login", func(c *fiber.Ctx) error {
type LoginInput struct {
Username string `json:"username"`
Password string `json:"password"`
}
var input LoginInput
if err := c.BodyParser(&input); err != nil {
return c.Status(400).JSON(fiber.Map{
"error": "Invalid input",
})
}
// 验证用户(示例)
if input.Username != "admin" || input.Password != "password" {
return c.Status(401).JSON(fiber.Map{
"error": "Invalid credentials",
})
}
// 创建Session
sess, err := store.Get(c)
if err != nil {
return err
}
sess.Set("user_id", 1)
sess.Set("username", input.Username)
sess.Save()
return c.JSON(fiber.Map{
"message": "Login successful",
})
})
// 获取用户信息
app.Get("/me", AuthRequired(store), func(c *fiber.Ctx) error {
sess, _ := store.Get(c)
return c.JSON(fiber.Map{
"user_id": sess.Get("user_id"),
"username": sess.Get("username"),
})
})
// 登出
app.Post("/logout", func(c *fiber.Ctx) error {
sess, err := store.Get(c)
if err != nil {
return err
}
sess.Destroy()
return c.JSON(fiber.Map{
"message": "Logout successful",
})
})
app.Listen(":3000")
}
五、Session数据操作 #
5.1 设置数据 #
go
sess.Set("key", "value")
sess.Set("user", fiber.Map{
"id": 1,
"name": "John",
})
5.2 获取数据 #
go
value := sess.Get("key")
// 类型断言
if user, ok := sess.Get("user").(fiber.Map); ok {
fmt.Println(user["name"])
}
5.3 删除数据 #
go
sess.Delete("key")
5.4 检查数据 #
go
if sess.Get("user_id") != nil {
// 已登录
}
5.5 获取Session ID #
go
sess, _ := store.Get(c)
sessionID := sess.ID()
5.6 重新生成Session ID #
go
sess.Regenerate()
六、安全最佳实践 #
6.1 Cookie安全配置 #
go
c.Cookie(&fiber.Cookie{
Name: "session",
Value: sessionID,
Secure: true, // 仅HTTPS
HTTPOnly: true, // 防止XSS
SameSite: "Strict", // 防止CSRF
MaxAge: 3600, // 限制有效期
Path: "/",
})
6.2 Session安全配置 #
go
var store = session.New(session.Config{
Expiration: 30 * time.Minute,
KeyLookup: "cookie:session_id",
Cookie: fiber.Cookie{
Secure: true,
HTTPOnly: true,
SameSite: "Strict",
},
})
6.3 防止Session劫持 #
go
func SecureSession(c *fiber.Ctx, sess *session.Session) {
// 绑定IP
sess.Set("ip", c.IP())
// 绑定User-Agent
sess.Set("user_agent", c.Get("User-Agent"))
}
func ValidateSession(c *fiber.Ctx, sess *session.Session) bool {
storedIP := sess.Get("ip")
storedUA := sess.Get("user_agent")
if storedIP != nil && storedIP != c.IP() {
return false
}
if storedUA != nil && storedUA != c.Get("User-Agent") {
return false
}
return true
}
七、总结 #
7.1 Cookie与Session对比 #
| 特性 | Cookie | Session |
|---|---|---|
| 存储位置 | 客户端 | 服务器 |
| 安全性 | 较低 | 较高 |
| 大小限制 | 4KB | 无限制 |
| 性能 | 高 | 需要存储开销 |
7.2 下一步 #
现在你已经了解了Cookie与Session,接下来让我们学习 文件上传下载,了解文件处理!
最后更新:2026-03-28