From eea341793f1ae94b091ee814bb992a51cd463b75 Mon Sep 17 00:00:00 2001 From: Jeff Billimek Date: Tue, 14 Aug 2018 07:02:10 -0400 Subject: [PATCH] use redis as a session store backend (#119) * support for custom github endpoints * implementing requested changes * using redis for session store if it is configured * using non-deprecated sessions lib * hard-coding redis session store private key for multiple instances * re-working GetPrivateKey to return stastic key only when redis is used * making config entries for redis sesion db and shared key --- config/example.yaml | 14 ++++++++------ deployments/cloudfoundry/run.sh | 1 + internal/handlers/auth.go | 23 +++++++++++++++++++---- internal/handlers/auth/auth.go | 2 +- internal/util/config.go | 6 +++++- internal/util/private.go | 7 ++++++- 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/config/example.yaml b/config/example.yaml index afecb68..a75d718 100644 --- a/config/example.yaml +++ b/config/example.yaml @@ -22,9 +22,11 @@ Proxy: # only relevant when using the proxy authbackend UserHeader: "X-Goog-Authenticated-User-ID" # pull the unique user ID from this header DisplayNameHeader: "X-Goog-Authenticated-User-Email" # pull the display naem from this header Redis: - Host: localhost:6379 # host:port combination; required - Password: replace me # redis connection password; optional; default is none - Db: 0 # redis index (https://redis.io/commands/select); optional; default is 0 - MaxRetries: 3 # maximum number of retries for a failed redis command - ReadTimeout: 3s # timeout for read operations; default is 3s. This is a golang time.ParseDuration string - WriteTimeout: 3s # timeout for write operations; default is 3s. This is a golang time.ParseDuration string + Host: localhost:6379 # host:port combination; required + Password: replace me # redis connection password; optional; default is none + Db: 0 # redis index (https://redis.io/commands/select); optional; default is 0 + MaxRetries: 3 # maximum number of retries for a failed redis command + ReadTimeout: 3s # timeout for read operations; default is 3s. This is a golang time.ParseDuration string + WriteTimeout: 3s # timeout for write operations; default is 3s. This is a golang time.ParseDuration string + SessionDB: 1 # redis session store index (https://redis.io/commands/select); optional; default is 1 + SharedKey: replace me # redis session store shared key; optional; default is "secret" diff --git a/deployments/cloudfoundry/run.sh b/deployments/cloudfoundry/run.sh index 3f8c1f6..9bbd2f3 100755 --- a/deployments/cloudfoundry/run.sh +++ b/deployments/cloudfoundry/run.sh @@ -13,6 +13,7 @@ fi if [ "$REDIS" != "" ]; then export GUS_REDIS_HOST="$(echo $VCAP_SERVICES | jq -r '.["'$REDIS_SERVICE_NAME'"][0].credentials.host'):$(echo $VCAP_SERVICES | jq -r '.["'$REDIS_SERVICE_NAME'"][0].credentials.port')" export GUS_REDIS_PASSWORD="$(echo $VCAP_SERVICES | jq -r '.["'$REDIS_SERVICE_NAME'"][0].credentials.password')" + export GUS_REDIS_SHARED_KEY=$GUS_REDIS_PASSWORD fi echo "#### Starting golang-url-shortener..." diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go index c7d7021..839dc88 100644 --- a/internal/handlers/auth.go +++ b/internal/handlers/auth.go @@ -9,14 +9,22 @@ import ( "github.com/sirupsen/logrus" jwt "github.com/dgrijalva/jwt-go" - "github.com/gin-gonic/contrib/sessions" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" + "github.com/gin-contrib/sessions/redis" "github.com/gin-gonic/gin" "github.com/pkg/errors" ) func (h *Handler) initOAuth() { - h.engine.Use(sessions.Sessions("backend", sessions.NewCookieStore(util.GetPrivateKey()))) - + switch backend := util.GetConfig().Backend; backend { + // use redis as the session store if it is configured + case "redis": + store, _ := redis.NewStoreWithDB(10, "tcp", util.GetConfig().Redis.Host, util.GetConfig().Redis.Password, util.GetConfig().Redis.SessionDB, util.GetPrivateKey()) + h.engine.Use(sessions.Sessions("backend", store)) + default: + h.engine.Use(sessions.Sessions("backend", cookie.NewStore(util.GetPrivateKey()))) + } h.providers = []string{} google := util.GetConfig().Google if google.Enabled() { @@ -39,7 +47,14 @@ func (h *Handler) initOAuth() { // initProxyAuth intializes data structures for proxy authentication mode func (h *Handler) initProxyAuth() { - h.engine.Use(sessions.Sessions("backend", sessions.NewCookieStore(util.GetPrivateKey()))) + switch backend := util.GetConfig().Backend; backend { + // use redis as the session store if it is configured + case "redis": + store, _ := redis.NewStoreWithDB(10, "tcp", util.GetConfig().Redis.Host, util.GetConfig().Redis.Password, util.GetConfig().Redis.SessionDB, util.GetPrivateKey()) + h.engine.Use(sessions.Sessions("backend", store)) + default: + h.engine.Use(sessions.Sessions("backend", cookie.NewStore(util.GetPrivateKey()))) + } h.providers = []string{} h.providers = append(h.providers, "proxy") h.engine.POST("/api/v1/auth/check", h.handleAuthCheck) diff --git a/internal/handlers/auth/auth.go b/internal/handlers/auth/auth.go index 8e3e8f7..9c49ff7 100644 --- a/internal/handlers/auth/auth.go +++ b/internal/handlers/auth/auth.go @@ -8,7 +8,7 @@ import ( "time" jwt "github.com/dgrijalva/jwt-go" - "github.com/gin-gonic/contrib/sessions" + "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" "github.com/mxschmitt/golang-url-shortener/internal/util" "github.com/pkg/errors" diff --git a/internal/util/config.go b/internal/util/config.go index 6ea4e47..42fe6ed 100644 --- a/internal/util/config.go +++ b/internal/util/config.go @@ -38,6 +38,8 @@ type redisConf struct { MaxRetries int `yaml:"MaxRetries" env:"MAX_RETRIES"` ReadTimeout string `yaml:"ReadTimeout" env:"READ_TIMEOUT"` WriteTimeout string `yaml:"WriteTimeout" env:"WRITE_TIMEOUT"` + SessionDB string `yaml:"SessionDB" env:"SESSION_DB"` + SharedKey string `yaml:"SharedKey" env:"SHARED_KEY"` } type oAuthConf struct { @@ -52,7 +54,7 @@ type proxyAuthConf struct { DisplayNameHeader string `yaml:"DisplayNameHeader" env:"DISPLAY_NAME_HEADER"` } -// config contains the default values +// Config contains the default values var Config = Configuration{ ListenAddr: ":8080", BaseURL: "http://localhost:3000", @@ -69,6 +71,8 @@ var Config = Configuration{ MaxRetries: 3, ReadTimeout: "3s", WriteTimeout: "3s", + SessionDB: "1", + SharedKey: "secret", }, } diff --git a/internal/util/private.go b/internal/util/private.go index ea5a587..1790820 100644 --- a/internal/util/private.go +++ b/internal/util/private.go @@ -35,5 +35,10 @@ func CheckForPrivateKey() error { // GetPrivateKey returns the private key func GetPrivateKey() []byte { - return privateKey + switch backend := GetConfig().Backend; backend { + case "redis": + return []byte(GetConfig().Redis.SharedKey) + default: + return privateKey + } }