Skip to content

Commit 398b235

Browse files
committed
refactor: improved auth middleware's AuthenticateFromCookie method implementation
1 parent 522eafe commit 398b235

File tree

4 files changed

+86
-80
lines changed

4 files changed

+86
-80
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ go 1.25.1
55
require (
66
github.com/ralvarezdev/go-flags v0.3.8
77
github.com/ralvarezdev/go-grpc v0.5.15
8-
github.com/ralvarezdev/go-json v0.2.2
8+
github.com/ralvarezdev/go-json v0.2.3
99
github.com/ralvarezdev/go-jwt v0.7.4
1010
github.com/ralvarezdev/go-rate-limiter v0.1.11
1111
github.com/ralvarezdev/go-reflect v0.3.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ github.com/ralvarezdev/go-flags v0.3.8 h1:b/doNRr2HsniEpz8NjbH2vxJH5WMeymIx0LAzD
2424
github.com/ralvarezdev/go-flags v0.3.8/go.mod h1:R3yVBYvzwqfOp26LidaiJ/zftVAnPC3pKunVpV/vosE=
2525
github.com/ralvarezdev/go-grpc v0.5.15 h1:ONyaMXDsa2D20oMUyqSUa0+vkPyN/yBjpdpQROkJNCU=
2626
github.com/ralvarezdev/go-grpc v0.5.15/go.mod h1:sWWaPkhXCJq5xQhTvBkfrbrZrdiZx6H8j4sAk/kk0so=
27-
github.com/ralvarezdev/go-json v0.2.2 h1:YN15JZr43TXmD9pLqazYTdi49gEdkI3vSM6mpCFX8tY=
28-
github.com/ralvarezdev/go-json v0.2.2/go.mod h1:85+1W7iK7NNEwgph/X7up69bqY5ug3Psqykjz+Mnq1I=
27+
github.com/ralvarezdev/go-json v0.2.3 h1:9WOY49UN5mTjylRJ7t+6Ak9CqywQoZQ4AbNaHXF1O5U=
28+
github.com/ralvarezdev/go-json v0.2.3/go.mod h1:85+1W7iK7NNEwgph/X7up69bqY5ug3Psqykjz+Mnq1I=
2929
github.com/ralvarezdev/go-jwt v0.7.4 h1:f9ovJubB/X1xL1cxeW+QNQ8y79Jh/YN9v74SiyYBYXY=
3030
github.com/ralvarezdev/go-jwt v0.7.4/go.mod h1:fXGHJ6oPHXgMNWlgR08emuxUklQKgEqgWsq69Jk7lDE=
3131
github.com/ralvarezdev/go-rate-limiter v0.1.11 h1:4YqXf8iOuwsGi5oCAwJSHAjq7xRlbbCPiLrg2b2kJtw=

http/middleware/auth/middleware.go

Lines changed: 82 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ func (m Middleware) authenticate(
105105
// Get the context from the request
106106
ctx := r.Context()
107107

108+
// Validate the token claims
108109
claims, err := m.validator.ValidateClaims(
109110
ctx,
110111
rawToken,
@@ -278,83 +279,61 @@ func (m Middleware) AuthenticateFromCookie(
278279
panic(ErrNilRefreshTokenFn)
279280
}
280281

281-
var cookieName string
282+
// Determine the cookie name based on the token type
283+
refreshTokenCookieName := *m.options.CookieRefreshTokenName
284+
accessTokenCookieName := *m.options.CookieAccessTokenName
285+
var currentCookieName string
282286
switch token {
283287
case gojwttoken.AccessToken:
284-
cookieName = *m.options.CookieAccessTokenName
288+
currentCookieName = accessTokenCookieName
285289
case gojwttoken.RefreshToken:
286-
cookieName = *m.options.CookieRefreshTokenName
290+
currentCookieName = refreshTokenCookieName
287291
}
288292

289-
// Create the fail handler function
290-
failHandler := m.authenticateFromCookieFailHandler(cookieName)
291-
292-
// Create the authenticate function
293-
var authenticateFn func(rawTokens map[gojwttoken.Token]string) func(next http.Handler) http.Handler
293+
// Create the fail handler functions
294+
accessTokenFailHandler := m.authenticateFromCookieFailHandler(accessTokenCookieName)
295+
refreshTokenFailHandler := m.authenticateFromCookieFailHandler(refreshTokenCookieName)
296+
var currentFailHandler FailHandlerFn
297+
switch token {
298+
case gojwttoken.AccessToken:
299+
currentFailHandler = accessTokenFailHandler
300+
case gojwttoken.RefreshToken:
301+
currentFailHandler = refreshTokenFailHandler
302+
}
294303

295304
//nolint:nestif // This function requires nested ifs for clarity
296-
authenticateFn = func(rawTokens map[gojwttoken.Token]string) func(next http.Handler) http.Handler {
297-
return func(next http.Handler) http.Handler {
298-
return http.HandlerFunc(
299-
func(w http.ResponseWriter, r *http.Request) {
300-
var (
301-
rawToken string
302-
cookie *http.Cookie
303-
err error
304-
ok bool
305-
)
306-
307-
// Get the cookie
308-
if rawTokens != nil {
309-
// Get the raw token from the map
310-
rawToken, ok = rawTokens[token]
311-
312-
// Return an error if the token is missing
313-
if !ok {
314-
failHandler(
315-
w,
316-
r,
317-
gonethttp.ErrCookieNotFound,
318-
gonethttp.ErrCodeCookieNotFound,
319-
)
320-
return
321-
}
322-
} else {
323-
// Get the cookie from the request
324-
cookie, err = r.Cookie(cookieName)
305+
return func(next http.Handler) http.Handler {
306+
return http.HandlerFunc(
307+
func(w http.ResponseWriter, r *http.Request) {
308+
var (
309+
rawToken string
310+
cookie *http.Cookie
311+
err error
312+
ok bool
313+
)
325314

326-
// Check if there was an error getting the cookie
327-
if err == nil {
328-
// Get the raw token from the cookie
329-
rawToken = cookie.Value
330-
} else if errors.Is(err, http.ErrNoCookie) {
331-
// Check if the token can be refreshed
332-
if token == gojwttoken.AccessToken && m.options.RefreshTokenFn != nil {
333-
// Refresh the token
334-
rawTokens, err = m.options.RefreshTokenFn(w, r)
335-
if err != nil {
336-
m.authenticateFromCookieFailHandler(*m.options.CookieRefreshTokenName)(
337-
w,
338-
r,
339-
err,
340-
ErrCodeFailedToRefreshToken,
341-
)
342-
return
343-
}
315+
// Get the cookie from the request
316+
cookie, err = r.Cookie(currentCookieName)
344317

345-
// authenticate again
346-
authenticateFn(rawTokens)(next).ServeHTTP(
347-
w,
348-
r,
349-
)
350-
return
351-
}
352-
}
318+
// Check if there was an error getting the cookie
319+
if err == nil {
320+
// Get the raw token from the cookie
321+
rawToken = cookie.Value
322+
} else if errors.Is(err, http.ErrNoCookie) {
323+
// Check if there's no option to refresh the token or if the token is a refresh token
324+
if token == gojwttoken.RefreshToken || m.options.RefreshTokenFn == nil {
325+
currentFailHandler(
326+
w,
327+
r,
328+
gonethttp.ErrCookieNotFound,
329+
gonethttp.ErrCodeCookieNotFound,
330+
)
331+
return
353332
}
354333

355-
// Check if the raw token is empty
356-
if rawToken == "" {
357-
failHandler(
334+
// Check if the refresh token cookie is present
335+
if _, err = r.Cookie(refreshTokenCookieName); err != nil {
336+
currentFailHandler(
358337
w,
359338
r,
360339
gonethttp.ErrCookieNotFound,
@@ -363,18 +342,45 @@ func (m Middleware) AuthenticateFromCookie(
363342
return
364343
}
365344

366-
// Call the authenticate function
367-
m.authenticate(
368-
token,
369-
rawToken,
370-
failHandler,
371-
)(next).ServeHTTP(
345+
// Refresh the token
346+
rawTokens, refreshErr := m.options.RefreshTokenFn(w, r)
347+
if refreshErr != nil {
348+
refreshTokenFailHandler(
349+
w,
350+
r,
351+
refreshErr,
352+
ErrCodeFailedToRefreshToken,
353+
)
354+
return
355+
}
356+
357+
// Get the raw token from the map, if not found set it to an empty string
358+
if rawToken, ok = rawTokens[token]; !ok {
359+
rawToken = ""
360+
}
361+
}
362+
363+
// Check if the raw token is empty
364+
if rawToken == "" {
365+
currentFailHandler(
372366
w,
373367
r,
368+
gonethttp.ErrCookieNotFound,
369+
gonethttp.ErrCodeCookieNotFound,
374370
)
375-
},
376-
)
377-
}
371+
return
372+
}
373+
374+
// Call the authenticate function
375+
m.authenticate(
376+
token,
377+
rawToken,
378+
currentFailHandler,
379+
)(next).ServeHTTP(
380+
w,
381+
r,
382+
)
383+
},
384+
)
378385
}
379-
return authenticateFn(nil)
380386
}

http/middleware/validator/middleware.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ func (m Middleware) CreateValidateFn(
180180
return validateFn, nil
181181
}
182182
}
183-
183+
184184
// Get the type of the request
185185
bodyType := goreflect.GetDereferencedType(bodyExample)
186186

0 commit comments

Comments
 (0)