我制作了自己的auth(和单会话auth)方法,用于将会话保存到redis,该方法是:
代码
before_request:
func (hs BeforeRequest) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !strings.Contains(r.RequestURI, "/login") && !strings.Contains(r.RequestURI, "/logout") {
// Check is user has `guid` cookie
Guid, err := r.Cookie("guid")
// if cookie not available, set cookie and redirect to login
if err != nil {
// Set the cookie
expiration := time.Now().Add(365 * 24 * time.Hour)
cookie := http.Cookie{Name: "guid", Value: helper.GenerateGuid(), Expires:expiration}
http.SetCookie(w, &cookie)
// Redirect to login
http.Redirect(w, r, "/login", 301)
return
} else {
// Return username that used by user (by it's Guid)
_, err := redisdb.Get(Guid.Value).Result()
if err != redis.Nil {
// Get active Guid by username, return active Guid
UsedFor, err := redisdb.Get(IsHasRedis).Result()
if err != redis.Nil && err == nil {
if UsedFor != Guid.Value {
fmt.Println("this account used in another session")
http.Redirect(w, r, "/login", 301)
return
}
} else {
// definitely not logged in
http.Redirect(w, r, "/login", 301)
return
}
} else {
// definitely not logged in
http.Redirect(w, r, "/login", 301)
return
}
}
}
// handle the request.
hs[0].ServeHTTP(w, r)
}
登录:
func LoginExecute(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
err := r.ParseForm() // Must be called before writing response
if err != nil {
fmt.Println(err)
} else {
if processRequest(r) {
Username, Password := r.Form["username"], r.Form["password"]
if len(Username) > 0 && len(Password) > 0 {
if len(Username[0]) <= 20 && len(Password[0]) <= 50 {
User := structs.Users{}
database, err := helper.DataDatabase()
if err != nil {
http.Error(w, "Couldn't Connect to Database", 500)
return
}
err = database.C("users").Find(bson.M{"username": Username[0]}).One(&User)
if err == nil {
CompareError := bcrypt.CompareHashAndPassword([]byte(User.Password), []byte(Password[0]))
if CompareError == nil {
Guid, err := r.Cookie("guid")
if err == nil {
redisdb.Set(Guid.Value, Username[0], 6 * time.Hour)
redisdb.Set(Username[0], Guid.Value, 6 * time.Hour)
http.Redirect(w, r, "/", 301)
} else {
http.Redirect(w, r, "/login?err=disabled-cookie", 301)
}
} else {
http.Redirect(w, r, "/login?err=password", 301)
}
} else {
http.Redirect(w, r, "/login?err=username", 301)
}
}
}
} else {
// recaptcha failed
http.Redirect(w, r, "/login?err=username", 301)
}
}
}
问题是,此auth方法不稳定,idk为什么但在用户成功登录后:
是的,只是不稳定
注意:
答案 0 :(得分:2)
“ 301”响应状态表示“已永久移动”,允许浏览器无限期缓存响应。改用302 Found进行重定向,或者根本不重定向(您可以立即提供登录页面)。
打开开发人员工具很可能会禁用缓存,从而使其正常工作。