Browse Source

Use session IDs instead of storing users in the cookies

merge-requests/1/head
meskio 5 years ago
parent
commit
27c608f4d3
  1. 21
      server/server.go
  2. 61
      server/session.go

21
server/server.go

@ -19,11 +19,14 @@ var tmpl = template.Must(template.ParseFiles(
type server struct {
ldap *ldap.Ldap
sess *sessionStore
}
// Serve lowry web site
func Serve(addr string, l *ldap.Ldap) error {
s := server{l}
var s server
s.ldap = l
s.sess = initSessionStore()
r := mux.NewRouter()
r.HandleFunc("/", s.homeHandler)
@ -39,11 +42,11 @@ func Serve(addr string, l *ldap.Ldap) error {
}
func (s *server) homeHandler(w http.ResponseWriter, r *http.Request) {
user := getUser(w, r)
if user == "" {
session := s.sess.get(w, r)
if session == nil {
tmpl.ExecuteTemplate(w, "login.html", false)
} else {
tmpl.ExecuteTemplate(w, "index.html", user)
tmpl.ExecuteTemplate(w, "index.html", session.user)
}
}
@ -57,18 +60,18 @@ func (s *server) loginHandler(w http.ResponseWriter, r *http.Request) {
return
}
setUser(user, w, r)
s.sess.set(user, w, r)
http.Redirect(w, r, "/", http.StatusFound)
}
func (s *server) logoutHandler(w http.ResponseWriter, r *http.Request) {
setUser("", w, r)
s.sess.del(w, r)
http.Redirect(w, r, "/", http.StatusFound)
}
func (s *server) passwordHandler(w http.ResponseWriter, r *http.Request) {
user := getUser(w, r)
if user == "" {
session := s.sess.get(w, r)
if session == nil {
http.Redirect(w, r, "/", http.StatusFound)
return
}
@ -86,7 +89,7 @@ func (s *server) passwordHandler(w http.ResponseWriter, r *http.Request) {
return
}
err := s.ldap.ChangePass(user, oldpass, pass)
err := s.ldap.ChangePass(session.user, oldpass, pass)
if err != nil {
tmpl.ExecuteTemplate(w, "password.html", "WrongOldpass")
} else {

61
server/session.go

@ -1,26 +1,65 @@
package server
import (
"encoding/base64"
"math/rand"
"net/http"
"time"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
)
var store = sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
type session struct {
user string
}
type sessionStore struct {
cookies *sessions.CookieStore
sessions map[string]session
}
func initSessionStore() *sessionStore {
rand.Seed(time.Now().UnixNano())
cookies := sessions.NewCookieStore(securecookie.GenerateRandomKey(64))
return &sessionStore{cookies, map[string]session{}}
}
func (store *sessionStore) set(user string, w http.ResponseWriter, r *http.Request) {
sessionID := genID()
store.sessions[sessionID] = session{user}
cookie, _ := store.cookies.Get(r, "session")
cookie.Values["id"] = sessionID
cookie.Save(r, w)
}
func setUser(user string, w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "session")
session.Values["user"] = user
session.Save(r, w)
func (store *sessionStore) get(w http.ResponseWriter, r *http.Request) *session {
cookie, _ := store.cookies.Get(r, "session")
sessionID, ok := cookie.Values["id"].(string)
if !ok {
return nil
}
session, ok := store.sessions[sessionID]
if !ok {
return nil
}
return &session
}
func getUser(w http.ResponseWriter, r *http.Request) string {
session, _ := store.Get(r, "session")
session.Save(r, w)
user, ok := session.Values["user"].(string)
func (store *sessionStore) del(w http.ResponseWriter, r *http.Request) {
cookie, _ := store.cookies.Get(r, "session")
sessionID, ok := cookie.Values["id"].(string)
if !ok {
return ""
return
}
return user
delete(cookie.Values, "id")
cookie.Save(r, w)
delete(store.sessions, sessionID)
}
func genID() string {
buff := make([]byte, 8)
rand.Read(buff)
return base64.StdEncoding.EncodeToString(buff)
}

Loading…
Cancel
Save