Skip to content

Commit 36c52f3

Browse files
committed
Swap to redis based store to prevent session race conditions
1 parent a981e21 commit 36c52f3

4 files changed

Lines changed: 34 additions & 18 deletions

File tree

appengine_templates/app.yaml.tpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ env_variables:
99
JWT_SECRET: _JWT_SECRET
1010
SESSION_SECRET: _SESSION_SECRET
1111
ENCRYPTION_SECRET: _ENCRYPTION_SECRET
12+
REDIS_SESSION_DB: _REDIS_SESSION_DB
1213
GIN_MODE: release
1314

1415
vpc_access_connector:

authenticate/authenticate.go

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -149,14 +149,15 @@ func (auth *Auth) Login(context *gin.Context, session sessions.Session) {
149149
}
150150

151151
func (auth *Auth) Logout(context *gin.Context, session sessions.Session) {
152+
session.Set(JWT_TOKEN_KEY, "")
152153
session.Clear()
154+
// session.Options(SessionOptions(true))
153155
err := session.Save()
154156
if err != nil {
155157
auth.notAuth(context)
156158
return
157159
}
158160
context.HTML(http.StatusOK, "logout.tmpl", gin.H{})
159-
context.Abort()
160161
}
161162

162163
func (auth *Auth) notAuth(context *gin.Context) {
@@ -176,6 +177,29 @@ func (auth *Auth) NotAuthWithError(context *gin.Context, errorMessage string) {
176177
context.Abort()
177178
}
178179

180+
func (auth *Auth) RefreshToken(context *gin.Context, session sessions.Session, claim *UACClaims) {
181+
signedToken, err := auth.JWTCrypto.EncryptJWT(claim.UAC, &claim.UacInfo, claim.AuthTimeout)
182+
if err != nil {
183+
auth.Logger.Error("Failed to Encrypt JWT", zap.Error(err))
184+
return
185+
}
186+
187+
if session.Get(JWT_TOKEN_KEY) == nil || session.Get(JWT_TOKEN_KEY).(string) == "" {
188+
auth.Logger.Info("Not refreshing JWT as it looks like the user has logged out",
189+
append(utils.GetRequestSource(context),
190+
zap.String("InstrumentName", claim.UacInfo.InstrumentName),
191+
zap.String("CaseID", claim.UacInfo.InstrumentName),
192+
)...)
193+
return
194+
}
195+
session.Set(JWT_TOKEN_KEY, signedToken)
196+
if err := session.Save(); err != nil {
197+
auth.Logger.Error("Failed to save JWT to session", zap.Error(err))
198+
return
199+
}
200+
return
201+
}
202+
179203
func (auth *Auth) isUac16() bool {
180204
return auth.UacKind == "uac16"
181205
}
@@ -191,18 +215,3 @@ func Forbidden(context *gin.Context) {
191215
context.HTML(http.StatusForbidden, "access_denied.tmpl", gin.H{})
192216
context.Abort()
193217
}
194-
195-
func (auth *Auth) RefreshToken(context *gin.Context, session sessions.Session, claim *UACClaims) {
196-
signedToken, err := auth.JWTCrypto.EncryptJWT(claim.UAC, &claim.UacInfo, claim.AuthTimeout)
197-
if err != nil {
198-
auth.Logger.Error("Failed to Encrypt JWT", zap.Error(err))
199-
return
200-
}
201-
202-
session.Set(JWT_TOKEN_KEY, signedToken)
203-
if err := session.Save(); err != nil {
204-
auth.Logger.Error("Failed to save JWT to session", zap.Error(err))
205-
return
206-
}
207-
return
208-
}

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
5757
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
5858
github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE=
5959
github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc=
60+
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff h1:RmdPFa+slIr4SCBg4st/l/vZWVe9QJKMXGO60Bxbe04=
6061
github.com/boj/redistore v0.0.0-20180917114910-cd5dcc76aeff/go.mod h1:+RTT1BOk5P97fT2CiHkbFQwkK3mjsFAP6zCYV2aXtjw=
6162
github.com/bradfitz/gomemcache v0.0.0-20180710155616-bc664df96737/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60=
6263
github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
@@ -166,6 +167,7 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx
166167
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
167168
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
168169
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
170+
github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0=
169171
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
170172
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
171173
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=

webserver/webserver.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"github.com/blendle/zapdriver"
1313
"github.com/gin-contrib/secure"
1414
"github.com/gin-contrib/sessions"
15-
"github.com/gin-contrib/sessions/cookie"
15+
"github.com/gin-contrib/sessions/redis"
1616
"github.com/gin-gonic/gin"
1717
"github.com/kelseyhightower/envconfig"
1818
"go.uber.org/zap"
@@ -31,6 +31,7 @@ var (
3131
)
3232

3333
type Config struct {
34+
RedisSessionDB string `default:"localhost:3389" split_words:"true"`
3435
SessionSecret string `required:"true" split_words:"true"`
3536
EncryptionSecret string `required:"true" split_words:"true"`
3637
CatiUrl string `required:"true" split_words:"true"`
@@ -100,7 +101,10 @@ func (server *Server) SetupRouter() *gin.Engine {
100101

101102
httpRouter.Use(secure.New(securityConfig))
102103

103-
store := cookie.NewStore([]byte(server.Config.SessionSecret), []byte(server.Config.EncryptionSecret))
104+
store, err := redis.NewStore(10, "tcp", server.Config.RedisSessionDB, "", []byte(server.Config.SessionSecret), []byte(server.Config.EncryptionSecret))
105+
if err != nil {
106+
log.Fatalf("Could not connect to session database: %s", err)
107+
}
104108
store.Options(sessions.Options{
105109
Path: "/",
106110
MaxAge: 60 * 60 * 24 * 30, // 30 days

0 commit comments

Comments
 (0)