Go语言实战案例:Cookie与Session基础

在 Web 开发中,HTTP 协议是无状态 的,每一次请求都是独立的。为了让服务器记住客户端的状态,我们需要使用 CookieSession

  • Cookie:存储在浏览器端的小数据,随请求一起发送给服务器。
  • Session:存储在服务器端的用户会话数据,通常通过 Cookie 中的 Session ID 来关联。

一、案例目标

我们要实现一个简单的会话系统:

    1. 用户第一次访问 /set 接口时,服务器设置一个 Cookie 记录用户名。
    1. 用户访问 /get 接口时,服务器读取 Cookie 并返回用户信息。
    1. 使用内存保存 Session 数据,让服务器记住用户的登录状态。

二、核心知识点

  • 设置 Cookiehttp.SetCookie(w, cookie)
  • 读取 Cookier.Cookie("name")
  • Session 存储 (简单版):用 map[string]string 在内存中存储用户会话数据
  • Session ID 生成 :用 crypto/rand 生成随机字符串

三、完整代码示例

go 复制代码
package main

import (
    "crypto/rand"
    "encoding/hex"
    "fmt"
    "net/http"
    "sync"
)

// 内存版 Session 存储
var (
    sessionStore = make(map[string]string)
    mu           sync.Mutex
)

// 生成随机 Session ID
func generateSessionID() string {
    b := make([]byte, 16)
    _, _ = rand.Read(b)
    return hex.EncodeToString(b)
}

// 设置 Session 和 Cookie
func setHandler(w http.ResponseWriter, r *http.Request) {
    username := r.URL.Query().Get("username")
    if username == "" {
        username = "游客"
    }

    // 创建 Session ID
    sessionID := generateSessionID()

    // 保存到服务器端 Session
    mu.Lock()
    sessionStore[sessionID] = username
    mu.Unlock()

    // 设置 Cookie
    http.SetCookie(w, &http.Cookie{
        Name:  "session_id",
        Value: sessionID,
        Path:  "/",
    })

    fmt.Fprintf(w, "Session 已创建,欢迎你:%s\n", username)
}

// 获取 Session
func getHandler(w http.ResponseWriter, r *http.Request) {
    cookie, err := r.Cookie("session_id")
    if err != nil {
        http.Error(w, "未找到会话,请先访问 /set", http.StatusUnauthorized)
        return
    }

    mu.Lock()
    username, exists := sessionStore[cookie.Value]
    mu.Unlock()

    if !exists {
        http.Error(w, "会话已失效", http.StatusUnauthorized)
        return
    }

    fmt.Fprintf(w, "欢迎回来,%s!\n", username)
}

func main() {
    http.HandleFunc("/set", setHandler)
    http.HandleFunc("/get", getHandler)

    fmt.Println("服务器启动:http://localhost:8080")
    http.ListenAndServe(":8080", nil)
}

四、运行与测试

    1. 启动服务器:
go 复制代码
go run main.go
    1. 设置 Session(访问 /set):
arduino 复制代码
curl "http://localhost:8080/set?username=Tom"

返回:

复制代码
Session 已创建,欢迎你:Tom

同时浏览器或客户端会收到一个 session_id Cookie。

    1. 获取 Session(访问 /get):
arduino 复制代码
curl "http://localhost:8080/get" --cookie "session_id=xxxx"

返回:

复制代码
欢迎回来,Tom!

五、运行原理

    1. 第一次访问 /set
    • • 服务器生成 session_id
    • • 在内存中保存 session_id -> username 映射
    • • 设置 Cookie 让浏览器保存 session_id
    1. 访问 /get
    • • 从 Cookie 读取 session_id
    • • 查询服务器端 Session 存储
    • • 找到对应用户名并返回

六、注意事项

    1. 内存版 Session 仅适合学习和测试
    • • 生产环境要使用 Redis、数据库等持久化存储
    1. Session 过期处理
    • • 生产环境要设置超时机制(可用 time.AfterFunc 定时清理)
    1. 安全性
    • • 使用 HTTPS 传输 Cookie(Secure: true
    • • 防止 XSS、CSRF 攻击

七、进阶扩展

  • • 使用 Go 第三方库(如 gorilla/sessions)管理 Session
  • • 将 Session 存储到 Redis,支持分布式部署
  • • 在 Cookie 中设置 HttpOnly、Secure 属性提升安全性
  • • 实现 Session 超时自动清理机制

相关推荐
汤姆yu18 分钟前
基于springboot的民间救援队救助系统
java·spring boot·后端·救援队
IT_陈寒31 分钟前
React性能优化实战:这5个Hooks技巧让我的应用快了40%
前端·人工智能·后端
江天澄1 小时前
HTML5 中常用的语义化标签及其简要说明
前端·html·html5
知识分享小能手1 小时前
jQuery 入门学习教程,从入门到精通, jQuery在HTML5中的应用(16)
前端·javascript·学习·ui·jquery·html5·1024程序员节
美摄科技1 小时前
H5短视频SDK,赋能Web端视频创作革命
前端·音视频
韩立学长1 小时前
基于Springboot的智慧管网灌溉系统i1agupa7(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
一 乐1 小时前
高校教务|教务管理|基于springboot+vue的高校教务管理系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·教务管理
黄毛火烧雪下1 小时前
React Native (RN)项目在web、Android和IOS上运行
android·前端·react native
fruge1 小时前
前端正则表达式实战合集:表单验证与字符串处理高频场景
前端·正则表达式
August_._1 小时前
【MySQL】触发器、日志、锁机制 深度解析
java·大数据·数据库·人工智能·后端·mysql·青少年编程