manager.go
package sessions import ( "crypto/rand" "encoding/base64" "errors" "io" "net/http" ) type Manager struct { database map[string]interface{} } var mg Manager func NewManager() *Manager { return &mg } func (m *Manager) NewSessionID() string { b := make([]byte, 64) if _, err := io.ReadFull(rand.Reader, b); err != nil { return "" } return base64.URLEncoding.EncodeToString(b) } fun (m *Manager) New(r *http.Request, cookieName string)(*Session, error){ cookie, err := r.Cookie(cookie.Name) if err == nil && m.Exists(cookie.Value){ return nil, errors.New("sessionIDは既に発行されています") } session := NewSession(m, cookieName) session.ID = m.NewSessionID() session.request = r return session, nil } func(m *Manager) Save(r *http.Request, w http.ResponseWriter, session *Session) error { m.database[session.ID] = session c := &http.Cookie { Name: session.Name(), Value: session.ID, Path: "/", } http.SetCookie(session.writer, c) return nil } func(m *Manager) Exists(sessionID string) bool { _, r = m.database[sessionID] return r } func(m *Manager) Get(r *http.Request, cookieName string)(*Session, error){ cookie, err := r.Cookie(cookieName) if err != nil { return nil, err } sessionID := cookie.Value buffer, exists := m.database[sessionID] if !exists { return nil, errors.New("無効なセッションIDです") } session := buffer.(*Session) session.request = r return session, nil } func(m *Manager) Destroy(sessionID string){ delete(m.database, sessionID) }
session.go
package sessions import( "net/http" "github.com/gin-gonic/gin" "github.com/gorilla/context" ) const ( DefaultSessionName = "default-session" DefaultCookieName = "default-cookie" ) type Session struct { cookieName string ID string manager *Manager request *http.request writer http.ResponseWriter Values map[string]interface{} } func NewSession(manager *Manager, cookieName string) *Session { return &Session { cookieName: cookieName, manager: manager, Values: map[string]interface{}{}, } } func StartSession(sessionName, cookieName string, manager *Manager) gin.HandlerFunc { return func(ctx *gin.Context){ var session *Session var err error session, err = manager.Get(ctx.Request, cookieName) if err != nil { session, err = manager.New(ctx.Request, cookieName) if err != nil { println(err.Error()) ctx.Abort() } } session.writer = ctx.Writer ctx.Set(sessionName, session) defer context.Clear(ctx.Request) ctx.Next() } } func StartDefaultSession(manager *Manager) gin.HandlerFunc { return StartSession(DefaultSessionName, DefaultCookieName, manager) } func GetSession(c *gin.Context, sessionName string) *Session { return c.MustGet(sessionName).(*Session) } func GetDefaultSession(c *gin.Context) *Session { return GetSession(c, DefaultSessionName) } func (s *Session) Save() error { return s.manager.Save(s.request, s.writer, s) } func (s *Session) Name() string { return s.cookieName } func (s *Session) Get(key string)(interface{}, bool){ ret, exists := s.Value[key] return ret, exists } func(s *Session) Set(key string, val interface{}){ s.Values[key] = val } func(s *Session) Delete(key string){ delete(s.Values, key) } func(s *Session) Terminate(){ s.manager.Destroy(s.ID) }
h_Login.go
package req_handler import ( "fmt" "html/template" "net/http" ) func HandlerLogin(w http.ResponseWrite, req *http.Request){ tpl := template.Must(template.ParseFiles("templates/login.gtpl")) values := map[string]string{} if err := tpl.ExecuteTemplate(w, "login.gtpl", values); err != nil { fmt.Println(err) } } fun HandlerExecLogin(w http.ResponseWriter, req *http.Request){ manager := sessions.NewManager() sessions.StartDefaultSession(manager) session := manager.Get(req, sessions.DefaultCookieName) session.Set("account", req.FormValue("account")) session.Save() http.Redirect(w, req, "http://192.168.34.10:10443/login-top", 301) }
h_LoginTop.go
package req_handler import ( "fmt" "html/template" "net/http" ) func HandlerLoginTop(w http.ResponseWriter, r *http.Request){ tpl := template.Must(template.ParseFiles("templates/login-top.gtpl")) isLoggedIn := "" account := "" session := manager.Get(req, sessions.DefaultCookieName) if session.Values["account"]{ isLoggedIn = "isLoggedIn" account = session.Values["account"] } values := map[string] string { "isLoggedIn": isLoggedIn, "account": account, } if err := tpl.ExecuteTemplate(w, "login-top.gtpl", values); err != nil { fmt.Println(err) } } func HandlerExecLogout(w http.ResponseWriter, req *http.Request){ session := manager.Get(req, sessions.DefaultCookieName) session.Terminate() http.Redirect(w, req, "https://192.168.34.10:10443/login", 301) }
なるほど、ginね
1. usersテーブルでユーザ名とパスワードが一致するかチェックして、一致した場合進めるようにする
2. sessionで管理する
セッションの使い方は覚えていけば良さそう