feat: store session server-side
This commit is contained in:
parent
2612c37671
commit
f660d8c0eb
|
|
@ -2,4 +2,4 @@
|
||||||
gin-bin
|
gin-bin
|
||||||
lishwist.db
|
lishwist.db
|
||||||
.env*.local
|
.env*.local
|
||||||
db/init_sql.go
|
server/db/init_sql.go
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,11 @@ import (
|
||||||
"lishwist/db"
|
"lishwist/db"
|
||||||
"lishwist/env"
|
"lishwist/env"
|
||||||
|
|
||||||
"github.com/gorilla/sessions"
|
"github.com/Teajey/sqlstore"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthMiddleware struct {
|
type AuthMiddleware struct {
|
||||||
Store *sessions.CookieStore
|
Store *sqlstore.Store
|
||||||
protectedHandler http.Handler
|
protectedHandler http.Handler
|
||||||
publicHandler http.Handler
|
publicHandler http.Handler
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +44,12 @@ func (auth *AuthMiddleware) ExpectUser(r *http.Request) *db.User {
|
||||||
func NewAuthMiddleware(protectedHandler http.Handler, publicHandler http.Handler) *AuthMiddleware {
|
func NewAuthMiddleware(protectedHandler http.Handler, publicHandler http.Handler) *AuthMiddleware {
|
||||||
gob.Register(&RegisterProps{})
|
gob.Register(&RegisterProps{})
|
||||||
gob.Register(&LoginProps{})
|
gob.Register(&LoginProps{})
|
||||||
store := sessions.NewCookieStore([]byte(env.JwtSecret))
|
store, err := db.NewSessionStore()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed to create store:", err)
|
||||||
|
}
|
||||||
store.Options.MaxAge = 86_400
|
store.Options.MaxAge = 86_400
|
||||||
|
store.Options.Secure = !env.InDev
|
||||||
|
store.Options.HttpOnly = true
|
||||||
return &AuthMiddleware{store, protectedHandler, publicHandler}
|
return &AuthMiddleware{store, protectedHandler, publicHandler}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,13 +43,9 @@ func (auth *AuthMiddleware) LoginPost(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
session, err := auth.Store.Get(r, "lishwist_user")
|
// NOTE: Overwriting any existing cookie or session here. So we don't care if there's an error
|
||||||
if err != nil {
|
session, _ := auth.Store.Get(r, "lishwist_user")
|
||||||
log.Println("Couldn't get jwt:", err)
|
session.ID = ""
|
||||||
props.GeneralError = "Something went wrong. Error code: Sokka"
|
|
||||||
auth.RedirectWithFlash(w, r, "/", "login_props", &props)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
session.Values["authorized"] = true
|
session.Values["authorized"] = true
|
||||||
session.Values["username"] = username
|
session.Values["username"] = username
|
||||||
if err := session.Save(r, w); err != nil {
|
if err := session.Save(r, w); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ func (auth *AuthMiddleware) LogoutPost(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, "Something went wrong. Error code: Iroh", http.StatusInternalServerError)
|
http.Error(w, "Something went wrong. Error code: Iroh", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.Options.MaxAge = 0
|
||||||
session.Values = nil
|
session.Values = nil
|
||||||
if err := session.Save(r, w); err != nil {
|
if err := session.Save(r, w); err != nil {
|
||||||
http.Error(w, "Something went wrong. Error code: Azula", http.StatusInternalServerError)
|
http.Error(w, "Something went wrong. Error code: Azula", http.StatusInternalServerError)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,10 @@ package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"lishwist/env"
|
||||||
|
|
||||||
|
"github.com/Teajey/sqlstore"
|
||||||
_ "github.com/glebarez/go-sqlite"
|
_ "github.com/glebarez/go-sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -26,3 +29,34 @@ func Init() error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSessionStore() (*sqlstore.Store, error) {
|
||||||
|
deleteStmt, err := database.Prepare("DELETE FROM session WHERE id = ?;")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to prepare delete statement: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
insertStmt, err := database.Prepare("INSERT INTO session (value) VALUES (?);")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to prepare insert statement: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
selectStmt, err := database.Prepare("SELECT value FROM session WHERE id = ?;")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to prepare select statement: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStmt, err := database.Prepare("UPDATE session SET value = ?2 WHERE id = ?1;")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Failed to prepare update statement: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s := sqlstore.NewSqlStore(database, sqlstore.Statements{
|
||||||
|
Delete: deleteStmt,
|
||||||
|
Insert: insertStmt,
|
||||||
|
Select: selectStmt,
|
||||||
|
Update: updateStmt,
|
||||||
|
}, []byte(env.JwtSecret))
|
||||||
|
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,4 +32,9 @@ CREATE TABLE IF NOT EXISTS "group_member" (
|
||||||
FOREIGN KEY("group_id") REFERENCES "group"("id"),
|
FOREIGN KEY("group_id") REFERENCES "group"("id"),
|
||||||
FOREIGN KEY("user_id") REFERENCES "user"("id")
|
FOREIGN KEY("user_id") REFERENCES "user"("id")
|
||||||
);
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS "session" (
|
||||||
|
"id" INTEGER NOT NULL UNIQUE,
|
||||||
|
"value" TEXT NOT NULL,
|
||||||
|
PRIMARY KEY("id" AUTOINCREMENT)
|
||||||
|
);
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ func (u *User) GetTodo() ([]Gift, error) {
|
||||||
var sent bool
|
var sent bool
|
||||||
var recipientName string
|
var recipientName string
|
||||||
var recipientRef string
|
var recipientRef string
|
||||||
rows.Scan(&id, &name, &sent, &recipientName, &recipientRef)
|
_ = rows.Scan(&id, &name, &sent, &recipientName, &recipientRef)
|
||||||
gift := Gift{
|
gift := Gift{
|
||||||
Id: id,
|
Id: id,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,11 @@ func GuaranteeEnv(key string) (variable string) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var JwtSecret = GuaranteeEnv("LISHWIST_JWT_SECRET")
|
var JwtSecret = GuaranteeEnv("LISHWIST_SESSION_SECRET")
|
||||||
var HostRootUrl = GuaranteeEnv("LISHWIST_HOST_ROOT_URL")
|
var HostRootUrl = GuaranteeEnv("LISHWIST_HOST_ROOT_URL")
|
||||||
var HostPort = os.Getenv("LISHWIST_HOST_PORT")
|
var HostPort = os.Getenv("LISHWIST_HOST_PORT")
|
||||||
var ServePort = GuaranteeEnv("LISHWIST_SERVE_PORT")
|
var ServePort = GuaranteeEnv("LISHWIST_SERVE_PORT")
|
||||||
|
var InDev = os.Getenv("LISHWIST_IN_DEV") != ""
|
||||||
var HostUrl = func() *url.URL {
|
var HostUrl = func() *url.URL {
|
||||||
rawUrl := HostRootUrl
|
rawUrl := HostRootUrl
|
||||||
if HostPort != "" {
|
if HostPort != "" {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
module lishwist
|
module lishwist
|
||||||
|
|
||||||
go 1.22.0
|
go 1.23
|
||||||
|
|
||||||
|
toolchain go1.23.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Teajey/sqlstore v0.0.6
|
||||||
github.com/glebarez/go-sqlite v1.22.0
|
github.com/glebarez/go-sqlite v1.22.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/sessions v1.2.2
|
github.com/gorilla/sessions v1.4.0
|
||||||
golang.org/x/crypto v0.22.0
|
golang.org/x/crypto v0.22.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
github.com/Teajey/sqlstore v0.0.3 h1:6Y1jz9/yw1cj/Z/jrii0s87RAomKWr/07B1auDgw8pg=
|
||||||
|
github.com/Teajey/sqlstore v0.0.3/go.mod h1:hjk0S593/2Q4QxkEXCgpThj9w5KWGTQi9JtgfziHXXk=
|
||||||
|
github.com/Teajey/sqlstore v0.0.4 h1:ATe25BD8cV0FUw4w2qlccx5m0c5kQI0K4ksl/LnSHsc=
|
||||||
|
github.com/Teajey/sqlstore v0.0.4/go.mod h1:hjk0S593/2Q4QxkEXCgpThj9w5KWGTQi9JtgfziHXXk=
|
||||||
|
github.com/Teajey/sqlstore v0.0.5 h1:WZvu54baa8+9n1sKQe9GuxBVwSISw+xCkw4VFSwwIs8=
|
||||||
|
github.com/Teajey/sqlstore v0.0.5/go.mod h1:hjk0S593/2Q4QxkEXCgpThj9w5KWGTQi9JtgfziHXXk=
|
||||||
|
github.com/Teajey/sqlstore v0.0.6 h1:kUEpA+3BKFHZl128MuMeYY6zVcmq1QmOlNyofcFEJOA=
|
||||||
|
github.com/Teajey/sqlstore v0.0.6/go.mod h1:hjk0S593/2Q4QxkEXCgpThj9w5KWGTQi9JtgfziHXXk=
|
||||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||||
|
|
@ -10,8 +18,8 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||||
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
|
||||||
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||||
|
|
|
||||||
|
|
@ -45,5 +45,8 @@ func main() {
|
||||||
|
|
||||||
http.Handle("/", authMiddleware)
|
http.Handle("/", authMiddleware)
|
||||||
|
|
||||||
http.ListenAndServe(":"+env.ServePort, nil)
|
err = http.ListenAndServe(":"+env.ServePort, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("Failed to listen and server:", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue