Reputation:
I am trying to authenticate a user (using email and password) in golang but I am having some problems with sessions. It seems like I cant retrieve the session value from /login/ to / (home) page.
User Registration
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(r.Form["passwordSignup"][0]), bcrypt.DefaultCost)
err = c.Insert(&model.UserModel{
Email: r.Form["emailSignup"][0],
Password: string(hashedPassword),
CreatedAt: time.Now(),
})
// TODO : should session management be made in here ???
// you can use gorilla sessions if you want as far it works
http.SetCookie(w, cookie)
http.Redirect(w, r, "/", 301) // goes to the homepage(only accessed by authenticated users)
Login
if r.Form["emailLogin"][0] == result.Email
&& bcrypt.CompareHashAndPassword([]byte(result.Password), []byte(r.Form["passwordLogin"][0])) == nil {
// TODO : Handling the session in here
http.Redirect(w, r, "/", 301) // goes to the home page
} else {
http.Redirect(w, r, "/login/", 301)
}
I checked this links too : http://shadynasty.biz/blog/2012/09/05/auth-and-sessions/ https://www.youtube.com/watch?v=p0tGnjW_xxI
Upvotes: 1
Views: 13732
Reputation: 485
If you're looking for a simple session management solution which uses Redis or Memcache as your session store, I suggest using Jeff (disclaimer: I wrote it).
After authenticating a user, you simply add their session like so:
func (s Server) Login(w http.ResponseWriter, r *http.Request) {
user = Authenticate(r)
if user != nil {
// Key must be unique to one user among all users
err := s.jeff.Set(r.Context(), w, user.Email)
// handle error
}
// finish login
}
Subsequent requests will automatically be authenticated once wrapped with the Jeff middleware. The library was built with simplicity in mind and was built as an alternative to the existing libraries out there.
See the readme for more details on usage and features:
https://github.com/abraithwaite/jeff#usage
Upvotes: 0
Reputation: 24300
Importantly, you should check all of your errors - e.g.:
- hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(r.Form["passwordSignup"][0]), bcrypt.DefaultCost)
# Check our error, especially for something as important as password hashing
+ hashedPassword, err := bcrypt.GenerateFromPassword([]byte(r.Form["passwordSignup"][0]), bcrypt.DefaultCost)
if err != nil {
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
return
}
A lot of your relevant cookie code is missing, but here's what it should look like:
cookie := &http.Cookie{
Name: "my_app",
Value: val, // Some encoded value
Path: "/", // Otherwise it defaults to the /login if you create this on /login (standard cookie behaviour)
MaxAge: 86400, // One day
}
http.SetCookie(w, cookie)
Alternatively, if you use gorilla/sessions (which I recommend because it correctly authenticates cookies), you would do the following:
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), 500)
return
}
session.Options.Path = "/"
session.Values["user"] = user
err := session.Save(r, w)
if err != nil {
http.Error(w, err.Error(), 500)
return
}
http.Redirect(w, r, "/", 301)
Upvotes: 5