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
在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在客户端和服务器之间传递,无需手动管理登录状态。


