Golang中Cookie重定向问题的解决方法
Golang中Cookie重定向问题的解决方法 大家好,我似乎无法解决这个问题。我有一个Golang网站,连接正常并能创建会话,但我想使用Cookie来重定向到预订页面。希望有人能帮助我,我似乎无法让重定向正常工作。我需要它能够检查用户、创建ID和会话,然后验证是否一切正常,接着创建Cookie并从登录页面重定向到预订页面。
GitHub: GitHub - KSCHNAPPIEN/golang-web
package main
import (
"database/sql"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"time"
_ "github.com/go-sql-driver/mysql"
"github.com/gorilla/sessions"
_ "github.com/gorilla/sessions"
)
type DatabaseConfig struct {
Username string `json:"user"`
Password string `json:"password"`
Host string `json:"host"`
Port int `json:"port"`
Database string `json:"dbname"`
}
var id bool
var dbc string
var userID int
var store = sessions.NewCookieStore([]byte("logging succes secrect key"))
func logError(err error) {
if err != nil {
log.Println(err)
}
}
func main() {
logFile, err := os.OpenFile("errors.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
log.Println(err)
}
defer logFile.Close()
log.SetOutput(logFile)
mux := http.NewServeMux()
// route naar url
mux.HandleFunc("/", RootHandler)
mux.HandleFunc("/Locatie", LocatieHandler)
mux.HandleFunc("/Login", LoginHandler)
mux.HandleFunc("/Booking", BookingHandler)
mux.HandleFunc("/Logout", LogoutHandler)
// read json file
configBytes, err := ioutil.ReadFile("Db.json")
if err != nil {
logError(err)
}
// setting up new struct
var config DatabaseConfig
if err := json.Unmarshal(configBytes, &config); err != nil {
log.Println(err)
}
// make connection database
dbc = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", config.Username, config.Password, config.Host, config.Port, config.Database)
db, err := sql.Open("mysql", dbc)
if err != nil {
logError(err)
}
defer db.Close()
if err := db.Ping(); err != nil {
log.Println(err)
}
http.ListenAndServe(":8080", mux)
}
type LoginResponse struct {
Success bool
UserID int
}
func checkLogin(w http.ResponseWriter, r *http.Request) LoginResponse {
username := r.FormValue("username")
password := r.FormValue("password")
db, err := sql.Open("mysql", dbc)
if err != nil {
log.Println(err)
return LoginResponse{Success: false, UserID: -1}
}
defer db.Close()
err = db.QueryRow("SELECT id FROM users WHERE username=? AND password=?", username, password).Scan(&userID)
if err != nil {
log.Println(err)
return LoginResponse{Success: false, UserID: -1}
}
sessionID := createSession(userID)
if sessionID == "" {
log.Println("Error creating session")
return LoginResponse{Success: false, UserID: -1}
}
sessionCookie := &http.Cookie{Name: "session_id", Value: sessionID, Path: "/", Expires: time.Now().Add(time.Duration(24) * time.Hour)}
http.SetCookie(w, sessionCookie)
return LoginResponse{Success: true, UserID: userID}
}
func RootHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, ` <h1>Fonteyn Vakantieparken</h1> <p>Vakantie parken voor een onvergeetelijke vakantie.</p> <ul> <li><a href="/Locatie">Locatie</a></li> <li><a href="/Login">Login</a></li> </ul> `)
}
func LocatieHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, ` <h1>Locatie</h1> <p>Wij zijn beschikbaar in meerder landen.</p> <ul> <li><a href="/">Home</a></li> <li><a href="/Login">Login</a></li> </ul> `)
}
func createSession(userID int) string {
// Create a new session in the database and return the session ID
db, err := sql.Open("mysql", dbc)
if err != nil {
log.Println(err)
return ""
}
defer db.Close()
// Create a unique session ID
sessionID := fmt.Sprintf("%d_%d", userID, time.Now().UnixNano())
_, err = db.Exec("INSERT INTO sessions (user_id, start_time, end_time) VALUES (?, NOW(), NOW())", userID)
if err != nil {
log.Println(err)
return ""
}
return sessionID
}
func LoginHandler(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session.Values["logged_in"] = false
session.Save(r, w)
if r.Method == http.MethodPost {
loginResponse := checkLogin(w, r)
if loginResponse.Success {
http.Redirect(w, r, "/Booking", http.StatusFound)
return
}
}
fmt.Fprintln(w, `
<h1>Fonteyn Vakantieparken</h1>
<p>Vakantie parken voor een onvergeetelijke vakantie.</p>
<form action="/Login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<br><br>
<input type="submit" value="Submit">
</form>
`)
}
func LogoutHandler(w http.ResponseWriter, r *http.Request) {
sessionCookie, _ := r.Cookie("session_id")
sessionCookie.MaxAge = -1
http.SetCookie(w, sessionCookie)
http.Redirect(w, r, "/", http.StatusFound)
}
func BookingHandler(w http.ResponseWriter, r *http.Request) {
// Check if the user is logged in
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Als de gebruiker niet is ingelogd, verwijs de gebruiker door naar de inlogpagina
if session.Values["logged_in"] != true {
http.Redirect(w, r, "/login", http.StatusFound)
return
}
}
func validateSession(w http.ResponseWriter, r *http.Request, sessionID string) bool {
db, err := sql.Open("mysql", dbc)
if err != nil {
log.Println(err)
return false
}
defer db.Close()
var userID int
err = db.QueryRow("SELECT user_id FROM sessions WHERE id = ? AND end_time > NOW()", sessionID).Scan(&userID)
if err != nil {
log.Println(err)
return false
}
if userID > 0 {
session, err1 := store.Get(r, "session-name")
if err1 != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return false
}
session.Values["logged_in"] = true
session.Save(r, w)
http.Redirect(w, r, "/booking", http.StatusFound)
return true
} else {
return false
}
}
更多关于Golang中Cookie重定向问题的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html
你好, 导入处理 Cookie 所需的必要包。在你的代码中,你导入了 “github.com/gorilla/sessions”,但使用方式不一致。请将导入更新为:
import (
"github.com/gorilla/sessions"
"net/http"
)
在你的 LoginHandler 函数中,将 “logged_in” 值设置为 true 后,需要保存会话。请按如下方式更新代码:
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session.Values["logged_in"] = true
err = session.Save(r, w)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, "/Booking", http.StatusFound)
请确保在你的 BookingHandler 函数中正确检索会话。
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
loggedIn, ok := session.Values["logged_in"].(bool)
if !ok || !loggedIn {
http.Redirect(w, r, "/Login", http.StatusFound)
return
}
// 继续处理其余的预订逻辑
使用安全的密钥配置你的 sessions.CookieStore 至关重要。请更新存储初始化代码以使用安全密钥:
store = sessions.NewCookieStore([]byte("your-secure-key-here"))
请记住将 "your-secure-key-here" 替换为一个强大且唯一的密钥。
请尝试这些建议,如果你遇到任何其他问题或有更多疑问,请随时在这里提问!
更多关于Golang中Cookie重定向问题的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在你的代码中,Cookie重定向问题主要出现在会话管理逻辑不一致上。以下是需要修正的关键部分:
问题分析
- 双重会话管理冲突:同时使用了自定义Cookie和gorilla/sessions
- 会话状态未正确设置:登录成功后未设置gorilla session的
logged_in标志 - 验证逻辑不完整:
BookingHandler缺少Cookie验证
修正后的代码
1. 修改LoginHandler
func LoginHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
loginResponse := checkLogin(w, r)
if loginResponse.Success {
// 设置gorilla session
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
session.Values["logged_in"] = true
session.Values["user_id"] = loginResponse.UserID
session.Save(r, w)
http.Redirect(w, r, "/Booking", http.StatusFound)
return
}
}
fmt.Fprintln(w, `
<h1>Fonteyn Vakantieparken</h1>
<p>Vakantie parken voor een onvergeetelijke vakantie.</p>
<form action="/Login" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<br>
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<br><br>
<input type="submit" value="Submit">
</form>
`)
}
2. 修改BookingHandler
func BookingHandler(w http.ResponseWriter, r *http.Request) {
// 检查gorilla session
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 检查自定义session cookie
sessionCookie, err := r.Cookie("session_id")
if err != nil {
http.Redirect(w, r, "/Login", http.StatusFound)
return
}
// 验证数据库中的session
if !validateSession(w, r, sessionCookie.Value) {
http.Redirect(w, r, "/Login", http.StatusFound)
return
}
// 检查登录状态
if loggedIn, ok := session.Values["logged_in"].(bool); !ok || !loggedIn {
http.Redirect(w, r, "/Login", http.StatusFound)
return
}
// 显示预订页面
fmt.Fprintln(w, `
<h1>Booking Page</h1>
<p>Welcome to the booking system!</p>
<a href="/Logout">Logout</a>
`)
}
3. 简化validateSession函数
func validateSession(w http.ResponseWriter, r *http.Request, sessionID string) bool {
db, err := sql.Open("mysql", dbc)
if err != nil {
log.Println(err)
return false
}
defer db.Close()
var userID int
err = db.QueryRow("SELECT user_id FROM sessions WHERE session_id = ? AND end_time > NOW()", sessionID).Scan(&userID)
if err != nil {
log.Println(err)
return false
}
return userID > 0
}
4. 修正createSession函数
func createSession(userID int) string {
db, err := sql.Open("mysql", dbc)
if err != nil {
log.Println(err)
return ""
}
defer db.Close()
sessionID := fmt.Sprintf("%d_%d", userID, time.Now().UnixNano())
// 确保sessions表有正确的列名
_, err = db.Exec("INSERT INTO sessions (user_id, session_id, start_time, end_time) VALUES (?, ?, NOW(), DATE_ADD(NOW(), INTERVAL 24 HOUR))",
userID, sessionID)
if err != nil {
log.Println(err)
return ""
}
return sessionID
}
关键修改点
- 统一会话管理:在
LoginHandler中同时设置自定义Cookie和gorilla session - 双重验证:在
BookingHandler中验证两种会话机制 - 正确的重定向:确保验证失败时重定向到登录页面
- 数据库一致性:修正session表的列名和查询逻辑
这些修改确保了Cookie创建、会话验证和重定向逻辑的一致性。

