Golang登录和登出功能问题排查
Golang登录和登出功能问题排查 大家好,我是Go语言的新手,正在开发一个简单的登录/登出流程。我能够成功登录和登出用户,但当我第二次登出用户并重新登录后,这次却无法登出。第一次用户登录时,在/test页面上能显示用户名,首次登出时也能重置cookie。但当我再次登录并登出时,登录验证检查的cookie却没有被重置。以下是我的代码,请帮忙看看。
package main
import (
"log"
"net/http"
"text/template"
"github.com/gorilla/sessions"
"github.com/gorilla/mux"
)
var t *template.Template
var store *sessions.CookieStore
func init() {
t = template.Must(template.ParseGlob("templates/*.html"))
store = sessions.NewCookieStore([]byte("t0p-s3cr3t"))
store.Options.HttpOnly = true
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/hello", helloHandler).Methods("GET")
r.HandleFunc("/forbidden", forbiddenHandler).Methods("GET")
r.HandleFunc("/login", loginGetHandler).Methods("GET")
r.HandleFunc("/login", loginPostHandler).Methods("POST")
r.HandleFunc("/test", testHandler).Methods("GET")
r.HandleFunc("/logout", logoutHandler)
r.HandleFunc("/", handler).Methods("GET")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
func loginGetHandler(w http.ResponseWriter, r *http.Request) {
page := struct {
PageTitle string
}{
PageTitle: "Login Here",
}
t.ExecuteTemplate(w, "login.html", page)
}
func loginPostHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.PostForm.Get("username")
session, _ := store.Get(r, "session")
session.Values["username"] = username
session.Save(r, w)
http.Redirect(w, r, "/test", 301)
}
func handler(w http.ResponseWriter, r *http.Request) {
page := struct {
PageTitle string
Name string
Age int
}{
PageTitle: "Welcome to new world of golang",
Name: "Deepak Singh Kushwah",
Age: 36,
}
t.ExecuteTemplate(w, "index.html", page)
}
func helloHandler(w http.ResponseWriter, r *http.Request) {
page := struct {
PageTitle string
Name string
Age int
}{
PageTitle: "Hello World Handler",
Name: "Hello World",
Age: 40,
}
t.ExecuteTemplate(w, "index.html", page)
}
func forbiddenHandler(w http.ResponseWriter, r *http.Request) {
page := struct {
PageTitle string
Name string
}{
PageTitle: "403",
Name: "403",
}
t.ExecuteTemplate(w, "forbidden.html", page)
}
func testHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session")
untyped, ok := session.Values["username"]
if !ok {
http.Redirect(w, r, "/forbidden", 301)
return
}
username, ok := untyped.(string)
if !ok || username == "" {
http.Redirect(w, r, "/forbidden", 301)
return
}
page := struct {
PageTitle string
Name string
}{
PageTitle: "TEST Handler",
Name: username,
}
t.ExecuteTemplate(w, "test.html", page)
}
func loginCheck(r *http.Request) bool {
session, _ := store.Get(r, "session")
untyped, ok := session.Values["username"]
if !ok {
return false
}
_, ok = untyped.(string)
if !ok {
return false
}
return true
}
func logoutHandler(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, "session")
checkErr(err)
session.Values["username"] = ""
err = session.Save(r, w)
checkErr(err)
http.Redirect(w, r, "/", 301)
}
func checkErr(e error) {
if e != nil {
log.Panic(e)
}
}
更多关于Golang登录和登出功能问题排查的实战教程也可以访问 https://www.itying.com/category-94-b0.html
太好了,你已经成功解决了问题!能否与我们分享一下你的解决方案是什么?
geosoft1:
在代码中可以使用一些代表HTTP状态码的常量作为正则表达式
是的,我使用了302而不是301,问题就解决了。感谢大家的支持。
但是303更好,因为它将所有请求转换为GET,所以如果你从POST、DELETE、UPDATE等操作进行重定向,它会自动转换为GET(这在99%的情况下都是你想要的)。例如,请参阅此解释:https://serverfault.com/questions/391181/examples-of-302-vs-303
引用 deepaksinghkushwah:
checkErr(err) http.Redirect(w, r, "/", 301)
不要使用表示永久移动的301状态码。这会让浏览器认为访问此URL没有必要,因为它已永久移动到根路径。请改用303"查看其他"状态码。
http.Redirect(w, r, "/", 301)
相比直接使用数字代码,您可以使用一些代表HTTP状态码的常量,这些常量已在IANA注册(参见https://golang.org/src/net/http/status.go)。
http.Redirect(w, r, "/", http.StatusSeeOther)


