package api import ( "time" "encoding/json" "net/http" "reichard.io/imagini/internal/models" // "github.com/lestrrat-go/jwx/jwt" // "github.com/lestrrat-go/jwx/jwa" // log "github.com/sirupsen/logrus" ) // https://www.calhoun.io/pitfalls-of-context-values-and-how-to-avoid-or-mitigate-them/ // https://pace.dev/blog/2018/05/09/how-I-write-http-services-after-eight-years.html // https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1#333c // https://www.alexedwards.net/blog/organising-database-access <---- best // - TLDR: Do what you're doing, but use closeures for the handlers func (api *API) loginHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { errorJSON(w, "Method is not supported.", http.StatusMethodNotAllowed) return } // Decode into Struct var creds models.APICredentials err := json.NewDecoder(r.Body).Decode(&creds) if err != nil { errorJSON(w, "Invalid parameters.", http.StatusBadRequest) return } // Validate if creds.User == "" || creds.Password == "" { errorJSON(w, "Invalid parameters.", http.StatusBadRequest) return } // Do login resp := api.Auth.AuthenticateUser(creds) if !resp { errorJSON(w, "Invalid credentials.", http.StatusUnauthorized) return } // Create tokens accessToken := api.Auth.CreateJWTAccessToken() refreshToken := api.Auth.CreateRefreshToken() // Set appropriate cookies accessCookie := http.Cookie{Name: "AccessToken", Value: accessToken} refreshCookie := http.Cookie{Name: "RefreshToken", Value: refreshToken} http.SetCookie(w, &accessCookie) http.SetCookie(w, &refreshCookie) // Response success successJSON(w, "Login success.", http.StatusOK) } func (api *API) logoutHandler(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { http.Error(w, "Method is not supported.", http.StatusMethodNotAllowed) return } // Do logout // TODO: Clear Session Server Side // Tell Client to Expire Token cookie := &http.Cookie{ Name: "Token", Value: "", Path: "/", Expires: time.Unix(0, 0), HttpOnly: true, } http.SetCookie(w, cookie) } func (api *API) refreshLoginHandler(w http.ResponseWriter, r *http.Request) { ok := api.Auth.ValidateRefreshToken() if !ok { // TODO: Clear Access & Refresh Cookies errorJSON(w, "Invalid credentials.", http.StatusUnauthorized) return } // Update token accessToken := api.Auth.CreateJWTAccessToken() accessCookie := http.Cookie{Name: "AccessToken", Value: accessToken} http.SetCookie(w, &accessCookie) // Response success successJSON(w, "Refresh success.", http.StatusOK) }