golang简单高效的HTTP会话管理与识别插件库sessionup的使用

Golang简单高效的HTTP会话管理与识别插件库sessionup的使用

简介

sessionup是一个简单但高效的HTTP会话管理和识别包,提供以下特性:

  • 轻松的会话管理:
    • 初始化
    • 请求认证
    • 检索所有会话
    • 撤销当前会话
    • 撤销所有其他会话
    • 撤销所有会话
  • 可选的会话识别(IP地址、操作系统、浏览器)
  • 通过中间件进行认证
  • 完全可定制,但有合理的默认值
  • 轻量级
  • 直观的API
  • 允许自定义会话存储

安装

go get github.com/jellydator/sessionup

基本使用示例

首先需要创建一个Manager实例:

package main

import (
	"net/http"
	"time"
	
	"github.com/jellydator/sessionup"
	"github.com/jellydator/sessionup/memstore"
)

func main() {
	// 创建内存存储,会话5分钟后过期
	store := memstore.New(time.Minute * 5)
	
	// 创建会话管理器
	manager := sessionup.NewManager(store)
	
	// 可以自定义配置
	// manager := sessionup.NewManager(store, 
	//     sessionup.Secure(false), 
	//     sessionup.ExpiresIn(time.Hour * 24))
	
	// 设置路由
	http.Handle("/login", loginHandler(manager))
	http.Handle("/", manager.Public(homeHandler()))
	http.Handle("/private", manager.Auth(privateHandler()))
	http.Handle("/logout", manager.Auth(logoutHandler(manager)))
	
	http.ListenAndServe(":8080", nil)
}

func loginHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 假设用户认证通过,获取用户ID
		userID := "12345"
		
		// 创建新会话,可以添加元数据
		err := manager.Init(w, r, userID, 
			sessionup.MetaEntry("permission", "write"),
			sessionup.MetaEntry("age", "30"))
		if err != nil {
			http.Error(w, "Failed to create session", http.StatusInternalServerError)
			return
		}
		
		w.Write([]byte("Login successful!"))
	}
}

func homeHandler() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Public home page"))
	}
}

func privateHandler() http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 从上下文中获取会话
		session, ok := sessionup.FromContext(r.Context())
		if !ok {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}
		
		w.Write([]byte("Private page for user: " + session.UserKey))
	}
}

func logoutHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 撤销当前会话
		if err := manager.Revoke(r.Context(), w); err != nil {
			http.Error(w, "Failed to logout", http.StatusInternalServerError)
			return
		}
		
		w.Write([]byte("Logged out successfully"))
	}
}

高级功能示例

// 获取当前用户的所有会话
func getAllSessionsHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		sessions, err := manager.FetchAll(r.Context())
		if err != nil {
			http.Error(w, "Failed to fetch sessions", http.StatusInternalServerError)
			return
		}
		
		// 处理会话列表
		for _, session := range sessions {
			// 打印每个会话的信息
			fmt.Printf("Session ID: %s, CreatedAt: %v\n", session.ID, session.CreatedAt)
		}
	}
}

// 撤销所有其他会话(保留当前会话)
func revokeOtherSessionsHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if err := manager.RevokeOther(r.Context()); err != nil {
			http.Error(w, "Failed to revoke other sessions", http.StatusInternalServerError)
			return
		}
		
		w.Write([]byte("Revoked all other sessions"))
	}
}

// 撤销所有会话(包括当前会话)
func revokeAllSessionsHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if err := manager.RevokeAll(r.Context(), w); err != nil {
			http.Error(w, "Failed to revoke all sessions", http.StatusInternalServerError)
			return
		}
		
		w.Write([]byte("Revoked all sessions"))
	}
}

存储实现

sessionup支持多种存储后端:

  • memstore - 内存存储实现(已包含在包中)
  • Redis存储实现
  • PostgreSQL存储实现
  • SQLite存储实现
  • Bolt存储实现

自定义存储需要实现Store接口。

限制

sessionup仅提供服务器端会话存储和管理,因为无法通过cookie存储撤销/检索不在传入请求中的会话的功能。

总结

sessionup是一个简单高效的Golang HTTP会话管理库,提供了完整的会话生命周期管理功能,包括创建、验证、检索和撤销会话等操作。它设计轻量,API直观,并支持多种存储后端,非常适合需要会话管理的Web应用程序。


更多关于golang简单高效的HTTP会话管理与识别插件库sessionup的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang简单高效的HTTP会话管理与识别插件库sessionup的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang HTTP会话管理库sessionup使用指南

sessionup是一个简单高效的Golang HTTP会话管理库,它提供了会话创建、存储和验证的功能。下面我将详细介绍如何使用sessionup来管理Web应用中的用户会话。

安装

首先安装sessionup库:

go get github.com/swithek/sessionup

基本使用

1. 初始化sessionup

package main

import (
	"net/http"
	"time"
	
	"github.com/swithek/sessionup"
)

func main() {
	// 创建sessionup管理器
	manager := sessionup.NewManager(
		sessionup.InMemStore(), // 使用内存存储(生产环境建议使用数据库)
		sessionup.Secure(false), // 开发环境可以禁用安全选项
	)
	
	// 设置HTTP服务器
	mux := http.NewServeMux()
	mux.HandleFunc("/login", loginHandler(manager))
	mux.HandleFunc("/protected", manager.With(protectedHandler))
	mux.HandleFunc("/logout", logoutHandler(manager))
	
	// 启动服务器
	http.ListenAndServe(":8080", manager.Use(mux))
}

2. 登录处理(创建会话)

func loginHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 验证用户凭据(这里简化处理)
		username := r.FormValue("username")
		password := r.FormValue("password")
		
		if username != "admin" || password != "password" {
			http.Error(w, "Invalid credentials", http.StatusUnauthorized)
			return
		}
		
		// 创建会话
		_, err := manager.Init(w, r, sessionup.Session{
			UserKey: username, // 用户标识
			ExpiresAt: time.Now().Add(24 * time.Hour), // 24小时后过期
		})
		
		if err != nil {
			http.Error(w, "Failed to create session", http.StatusInternalServerError)
			return
		}
		
		w.Write([]byte("Login successful"))
	}
}

3. 受保护路由处理

func protectedHandler(w http.ResponseWriter, r *http.Request) {
	// 从上下文中获取会话信息
	session, ok := sessionup.FromContext(r.Context())
	if !ok {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}
	
	// 使用会话中的用户信息
	w.Write([]byte("Welcome " + session.UserKey))
}

4. 登出处理

func logoutHandler(manager *sessionup.Manager) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		// 终止当前会话
		err := manager.Revoke(r.Context(), w)
		if err != nil {
			http.Error(w, "Failed to logout", http.StatusInternalServerError)
			return
		}
		
		w.Write([]byte("Logged out successfully"))
	}
}

高级配置

使用数据库存储会话

import (
	"database/sql"
	_ "github.com/lib/pq"
	"github.com/swithek/sessionup/pgstore"
)

func main() {
	// 连接PostgreSQL数据库
	db, err := sql.Open("postgres", "postgres://user:pass@localhost/dbname")
	if err != nil {
		panic(err)
	}
	
	// 创建PostgreSQL存储
	store, err := pgstore.New(db, pgstore.TableName("sessions"))
	if err != nil {
		panic(err)
	}
	
	// 使用数据库存储创建管理器
	manager := sessionup.NewManager(store)
	
	// ...其余代码
}

自定义会话过期时间

manager := sessionup.NewManager(
	sessionup.InMemStore(),
	sessionup.ExpiresIn(24 * time.Hour), // 默认24小时过期
	sessionup.IdleTimeout(30 * time.Minute), // 30分钟不活动后过期
)

CSRF保护

manager := sessionup.NewManager(
	sessionup.InMemStore(),
	sessionup.CSRF(true), // 启用CSRF保护
)

最佳实践

  1. 生产环境:不要使用内存存储,应该使用数据库存储(如PostgreSQL、MySQL等)
  2. 安全配置:在生产环境中确保启用Secure选项和CSRF保护
  3. 会话过期:根据应用需求设置合理的会话过期时间
  4. 用户标识:UserKey应该是唯一的用户标识符,如用户ID或用户名

sessionup提供了简单而强大的会话管理功能,通过上述示例你可以快速集成到你的Go Web应用中。根据你的具体需求,可以进一步定制会话的存储、过期策略和安全设置。

回到顶部