网易首页 > 网易号 > 正文 申请入驻

go语言 - 会话机制之session

0
分享至

Go 官方只有 http.cookie,没有官方的 Session 包。

也就是说:

  • Cookie:官方一等公民
  • Session:官方不提供
一、Go 官方对 Cookie 的支持(很完整)

在标准库里,Cookie 是完整内建的

相关 API 都在:

net/http
二、那为什么 Go 官方不提供 Session?

这是设计哲学问题

1、session ≠ HTTP 标准

  • Cookie 是HTTP 标准的一部分
  • Session 是应用层概念
  • Session 的实现方式五花八门:
    • 内存
    • Redis
    • 文件
    • JWT(甚至没 Session)

官方没法“选边站”

2、Go 的设计哲学:最小但通用

Go 官方库的原则是:

只做通用、底层、稳定的东西

Session 涉及:

  • 存储方案
  • 过期策略
  • 分布式
  • 安全策略
  • 业务模型

一旦官方出 Session:

  • 就等于帮你做架构决策
  • 很容易限制场景
3、对比一下其他语言你就懂了PHP

$_SESSION["user_id"] = 1;

简单,但:

  • 强绑定 Cookie
  • 强绑定文件 / 内存
  • 不利于分布式
Java(Servlet)

HttpSession session = Request.getSession();

重、复杂、历史包袱

Go

“我给你工具,你自己搭积木”
三、那 Go 官方有没有“接近 Session 的东西”?有,但很底层1、context.Context❌ 不是 Session

ctx := r.Context()
  • 只在一次请求链路内
  • 不跨请求
  • 用于超时 / 取消 / trace

不能用来做登录态

2、http.Request/ResponseWriter

只负责:

  • Header
  • Cookie
  • Body

不碰业务状态

四、Go 社区是怎么解决 Session 的?常用第三方库1、gorilla/sessions(最经典)

store := sessions.NewCookieStore([]byte("secret"))session, _ := store.Get(r, "mysession")session.Values["user_id"] = 1session.Save(r, w)

支持:

  • Cookie
  • Filesystem
  • Redis(插件)
2、gin-contrib/sessions(Gin 生态)

sessions.Default(c).Set("user_id", 1)
五、Go 官方“默认推荐”的方式是什么?

不是 Session,而是:

自己实现 / 使用第三方 / 或用 Token(JWT)

所以你会看到很多 Go 项目:

  • 微服务:JWT / OAuth
  • 单体 Web:Session + Redis
  • API 服务:Token + Header
六、一个完整实现示例6.1、示例目标

实现一个最小但完整的登录系统:

  • /login:登录,创建 Session
  • /profile:需要登录才能访问
  • /logout:退出登录,销毁 Session

技术点:

  • Cookie 保存 session_id
  • 服务端内存保存 Session
  • 中间件校验登录态
6.2、整体结构

请求└── Cookie: session_idGo Server├── SessionStore(map)├── 登录校验└── 业务处理
6.3、完整可运行代码
直接 go run main.go 就能用

package mainimport ("fmt""log""math/rand""net/http""sync""time"// ===== 1. Session 结构 =====type Session struct {UserID    intUsername  stringExpiresAt time.Time// ===== 2. Session 存储 =====var (sessionStore = make(map[string]*Session)mu           sync.Mutex// ===== 3. 生成 SessionID =====func newSessionID() string {return fmt.Sprintf("%d_%d", time.Now().UnixNano(), rand.Int())// ===== 4. 创建 Session =====func createSession(w http.ResponseWriter, userID int, username string) {sid := newSessionID()mu.Lock()sessionStore[sid] = &Session{UserID:    userID,Username: username,ExpiresAt: time.Now().Add(30 * time.Minute),mu.Unlock()http.SetCookie(w, &http.Cookie{Name:     "session_id",Value:    sid,Path:     "/",HttpOnly: true,// ===== 5. 获取 Session =====func getSession(r *http.Request) (*Session, bool) {cookie, err := r.Cookie("session_id")if err != nil {return nil, falsemu.Lock()defer mu.Unlock()sess, ok := sessionStore[cookie.Value]if !ok {return nil, falseif sess.ExpiresAt.Before(time.Now()) {delete(sessionStore, cookie.Value)return nil, falsereturn sess, true// ===== 6. 销毁 Session =====func destroySession(w http.ResponseWriter, r *http.Request) {cookie, err := r.Cookie("session_id")if err == nil {mu.Lock()delete(sessionStore, cookie.Value)mu.Unlock()http.SetCookie(w, &http.Cookie{Name:   "session_id",Value: "",Path:  "/",MaxAge: -1,// ===== 7. 登录接口 =====func loginHandler(w http.ResponseWriter, r *http.Request) {// 模拟账号校验username := r.FormValue("username")password := r.FormValue("password")if username != "admin" || password != "123456" {w.WriteHeader(http.StatusUnauthorized)w.Write([]byte("login failed"))returncreateSession(w, 1, username)w.Write([]byte("login success"))// ===== 8. 需要登录的接口 =====func profileHandler(w http.ResponseWriter, r *http.Request) {sess, ok := getSession(r)if !ok {w.WriteHeader(http.StatusUnauthorized)w.Write([]byte("please login"))returnw.Write([]byte("hello " + sess.Username))// ===== 9. 退出登录 =====func logoutHandler(w http.ResponseWriter, r *http.Request) {destroySession(w, r)w.Write([]byte("logout success"))// ===== 10. main =====func main() {rand.Seed(time.Now().UnixNano())http.HandleFunc("/login", loginHandler)http.HandleFunc("/profile", profileHandler)http.HandleFunc("/logout", logoutHandler)log.Println("server running at :8080")log.Fatal(http.ListenAndServe(":8080", nil))
6.4、如何测试(一步步来)1、登录

curl -i -X POST \-d "username=admin&password=123456" \http://localhost:8080/login

你会看到:

Set-Cookie: session_id=xxx; HttpOnly
2、带 Cookie 访问受保护接口

curl -b "session_id=xxx" http://localhost:8080/profile

输出:

hello admin
3、退出登录

curl -b "session_id=xxx" http://localhost:8080/logout
6.5、这套代码覆盖的核心点
  • ✔ SessionID 随机生成
  • ✔ Cookie + HttpOnly
  • ✔ Session 过期时间
  • ✔ 并发安全(sync.Mutex)
  • ✔ 登录 / 校验 / 退出完整流程
6.6、真实项目需要改动的地方

一定要改的地方:

  1. map ➜Redis
  2. SessionID ➜更强随机(UUID / crypto/rand)
  3. 加:
  4. HTTPS
  5. Secure Cookie
  6. CSRF 防护
  7. Session 自动续期(滑动过期)
6.7、一句话总结
登录本质就是:服务器创建 Session,客户端保存 SessionID,之后每次请求用 SessionID 找回用户身份。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
美司法部公布文件爆“马斯克曾协调个人日程试图前往爱泼斯坦小岛”,马斯克最新回应

美司法部公布文件爆“马斯克曾协调个人日程试图前往爱泼斯坦小岛”,马斯克最新回应

环球网资讯
2026-01-31 18:03:42
1949年傅作义任水利部长遭闲置,主席当面质问,周恩来听闻当即发火

1949年傅作义任水利部长遭闲置,主席当面质问,周恩来听闻当即发火

磊子讲史
2026-01-14 10:12:21
1斤瓜子价格贵过猪肉,高端炒货价格猛涨至200元/斤

1斤瓜子价格贵过猪肉,高端炒货价格猛涨至200元/斤

21世纪经济报道
2026-01-31 21:53:34
库里核磁结果出炉!确诊髌股关节综合症 再缺阵7场将无缘评奖

库里核磁结果出炉!确诊髌股关节综合症 再缺阵7场将无缘评奖

罗说NBA
2026-02-01 09:40:36
从丰田车看中国制造的底色:后工业时代的断层

从丰田车看中国制造的底色:后工业时代的断层

生命可以承受之轻
2026-01-29 09:27:20
留着生能不能入职能部门,看央级党刊怎么说

留着生能不能入职能部门,看央级党刊怎么说

林中木白
2026-02-01 16:44:48
著名演员谭凯卖掉北京房产、注销北京户口,回青岛开一家饺子馆

著名演员谭凯卖掉北京房产、注销北京户口,回青岛开一家饺子馆

阿雹娱乐
2026-01-22 14:20:50
李思思不容易,为带货跑内蒙古扎麻花辫子扮少女,身材肥硕像大姐

李思思不容易,为带货跑内蒙古扎麻花辫子扮少女,身材肥硕像大姐

乐悠悠娱乐
2026-02-01 09:12:16
达成了!第二笔重磅交易!湖人彻底无缘2米01侧翼

达成了!第二笔重磅交易!湖人彻底无缘2米01侧翼

篮球实战宝典
2026-02-01 16:37:00
昨天顿悟,为什么塔利班和伊朗神权也有人支持?

昨天顿悟,为什么塔利班和伊朗神权也有人支持?

修明札记
2026-01-31 11:39:24
陕甘之战——汉人最伟大的一场巅峰战役,带领华夏重回世界之巅

陕甘之战——汉人最伟大的一场巅峰战役,带领华夏重回世界之巅

小豫讲故事
2026-01-31 06:00:10
利物浦球员穿上了新赞助商的服装,球迷调侃萨拉赫像火车司机

利物浦球员穿上了新赞助商的服装,球迷调侃萨拉赫像火车司机

懂球帝
2026-02-01 12:37:35
员工一天如厕超6个小时!被公司解雇后索赔20多万元,法院判了

员工一天如厕超6个小时!被公司解雇后索赔20多万元,法院判了

环球网资讯
2026-02-01 14:58:53
青楼出身,无法生育被休,改嫁上将连生11子,人人敬重的广东之母

青楼出身,无法生育被休,改嫁上将连生11子,人人敬重的广东之母

抽象派大师
2026-01-31 10:49:57
好言难劝该死的鬼?赴日旅游警示下,执意飞日本的国人到底图什么

好言难劝该死的鬼?赴日旅游警示下,执意飞日本的国人到底图什么

墨山看客
2026-02-01 14:27:02
TOP14位身高170以上的女神,有颜有灯有演技

TOP14位身高170以上的女神,有颜有灯有演技

素然追光
2026-01-02 02:45:02
央媒怒批、坑害老百姓!臭名昭著的几个相声演员,各个难以原谅

央媒怒批、坑害老百姓!臭名昭著的几个相声演员,各个难以原谅

无力的滋味
2026-02-01 11:32:33
访华4天签多份文件 斯塔默回怼特朗普更有底气

访华4天签多份文件 斯塔默回怼特朗普更有底气

看看新闻Knews
2026-02-01 00:04:11
闫学晶眼下最发愁的是如何留住儿媳妇,她清楚自儿子配不上梦迪

闫学晶眼下最发愁的是如何留住儿媳妇,她清楚自儿子配不上梦迪

观察鉴娱
2026-01-19 09:28:59
8000元餐费吓跑相亲男,女子独立支付后索赔,男子有错吗?

8000元餐费吓跑相亲男,女子独立支付后索赔,男子有错吗?

然哥闲聊
2026-02-01 16:57:04
2026-02-01 17:32:49
冒泡泡的鱼儿
冒泡泡的鱼儿
每天带来社会资讯
498文章数 15106关注度
往期回顾 全部

科技要闻

腾讯元宝宣布:10亿现金红包,今日开抢

头条要闻

男子年会抽中10万元彩票和苹果17ProMax 公司人士回应

头条要闻

男子年会抽中10万元彩票和苹果17ProMax 公司人士回应

体育要闻

锁喉吃红牌+扇耳光 英超15人打群架

娱乐要闻

马年春晚第三次联排,多位明星现身

财经要闻

黄仁勋台北"夜宴":汇聚近40位台企高管

汽车要闻

岚图汽车1月交付10515辆 同比增长31%

态度原创

教育
房产
时尚
本地
健康

教育要闻

10秒钟学会绝对值

房产要闻

藏不住的小城大事,海澄新城执掌自贸港风口,进阶兑现美好生活新篇

伊姐周六热推:电视剧《年少有为》;电视剧《有罪之身》......

本地新闻

云游中国|拨开云雾,巫山每帧都是航拍大片

耳石症分类型,症状大不同

无障碍浏览 进入关怀版