Golang如何实现已登录用户的会话管理

Golang如何实现已登录用户的会话管理 例如,我有一个用于用户登录系统的 REST 端点

func Login(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	rName := r.URL.Query().Get("username")
	rPass := r.URL.Query().Get("password")
	for _, u := range users {
		if u.Username == rName {
			if u.Password == rPass {
				loggedIn[u.ID] = struct{}{} // 我认为这不是实现用户会话的首选方案
				return
			}
		}
	}
	http.Error(w, "Invalid username/password supplied", 400)
	return
}

有没有办法将用户保存到会话中,之后只需检查会话中的某些内容就能判断用户是否已登录?顺便说一句,我正在使用 Gorilla Mux,所以可能有一个针对 Gorilla Mux 的特定解决方案?


更多关于Golang如何实现已登录用户的会话管理的实战教程也可以访问 https://www.itying.com/category-94-b0.html

3 回复

是的,Gorilla 提供了会话管理功能。请查看:https://www.gorillatoolkit.org/pkg/sessions

更多关于Golang如何实现已登录用户的会话管理的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我目前使用:

GitHub图标

GitHub

头像

golangcollege/sessions

适用于 Go 1.11+ 的会话管理。通过在 GitHub 上创建帐户来为 golangcollege/sessions 开发做出贡献。

谢谢!

在Golang中实现会话管理,推荐使用Gorilla Sessions库,它与Gorilla Mux配合良好。以下是完整的实现方案:

首先安装必要的包:

go get github.com/gorilla/sessions

然后实现会话管理:

import (
    "net/http"
    "github.com/gorilla/sessions"
)

var store = sessions.NewCookieStore([]byte("your-secret-key"))

func Login(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Type", "application/json")
    
    rName := r.URL.Query().Get("username")
    rPass := r.URL.Query().Get("password")
    
    for _, u := range users {
        if u.Username == rName && u.Password == rPass {
            session, _ := store.Get(r, "user-session")
            session.Values["authenticated"] = true
            session.Values["userID"] = u.ID
            session.Values["username"] = u.Username
            session.Save(r, w)
            
            w.WriteHeader(http.StatusOK)
            json.NewEncoder(w).Encode(map[string]string{"message": "Login successful"})
            return
        }
    }
    
    http.Error(w, "Invalid username/password supplied", http.StatusBadRequest)
}

func Logout(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "user-session")
    session.Values["authenticated"] = false
    session.Values["userID"] = nil
    session.Values["username"] = nil
    session.Save(r, w)
    
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{"message": "Logout successful"})
}

// 中间件检查用户是否已登录
func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        session, _ := store.Get(r, "user-session")
        
        if auth, ok := session.Values["authenticated"].(bool); !ok || !auth {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        
        next.ServeHTTP(w, r)
    })
}

// 获取当前用户信息
func GetCurrentUser(w http.ResponseWriter, r *http.Request) {
    session, _ := store.Get(r, "user-session")
    
    userID := session.Values["userID"]
    username := session.Values["username"]
    
    response := map[string]interface{}{
        "userID":   userID,
        "username": username,
    }
    
    w.Header().Set("Content-Type", "application/json")
    json.NewEncoder(w).Encode(response)
}

在Gorilla Mux路由中使用:

func main() {
    r := mux.NewRouter()
    
    // 公开路由
    r.HandleFunc("/login", Login).Methods("POST")
    r.HandleFunc("/logout", Logout).Methods("POST")
    
    // 需要认证的路由
    authRouter := r.PathPrefix("/api").Subrouter()
    authRouter.Use(AuthMiddleware)
    authRouter.HandleFunc("/user", GetCurrentUser).Methods("GET")
    authRouter.HandleFunc("/protected", SomeProtectedHandler).Methods("GET")
    
    http.ListenAndServe(":8080", r)
}

对于生产环境,建议使用更安全的存储方式:

// 使用文件系统存储替代Cookie存储
var store = sessions.NewFilesystemStore("", []byte("your-secret-key"))

// 或者使用Redis存储
import "github.com/boj/redistore"

var store, _ = redistore.NewRediStore(10, "tcp", ":6379", "", []byte("your-secret-key"))

这个方案提供了完整的会话管理功能,包括登录、注销、认证中间件和用户信息获取。会话数据会自动通过Cookie在客户端和服务器之间传递,无需手动管理登录状态。

回到顶部