fix: /fetch, /refresh, /update and /change-password accept the session cookies the jwt guard reads
The four routes (and the other signed-in routes through authenticate) read the bearer header, then the token and auth_token cookies, through classes.SessionToken and one cookie-aware guard. A bearer header still wins and no credentials stays 401 with the old bodies. A cookie-carried /refresh answers the rotated token in the body and writes no cookie.
This commit is contained in:
@@ -20,6 +20,14 @@ import (
|
||||
// the Authorization header, in the same order (plugin.go Boot).
|
||||
var sessionCookieNames = []string{"token", "auth_token"}
|
||||
|
||||
// SessionCookieNames returns a copy of the cookie names the plugin's "jwt"
|
||||
// guard (plugin.go Boot) reads after the Authorization header, in order.
|
||||
// A handler that builds its own guard passes them to bouncer.NewJWTGuard so
|
||||
// it reads the same token as SessionToken and jwt.auth.
|
||||
func SessionCookieNames() []string {
|
||||
return slices.Clone(sessionCookieNames)
|
||||
}
|
||||
|
||||
// RequestUser returns the signed-in user of r for handlers that run without
|
||||
// the jwt.auth middleware and must also serve anonymous requests (an OAuth
|
||||
// provider's authorize page, for example). The token is read and checked
|
||||
@@ -35,7 +43,7 @@ func RequestUser(ctx context.Context, app *backpack.App, r *http.Request) (*mode
|
||||
if r == nil {
|
||||
return nil, nil
|
||||
}
|
||||
raw := sessionToken(r)
|
||||
raw := SessionToken(r)
|
||||
if raw == "" {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -209,9 +217,12 @@ func refreshWindow(app *backpack.App) time.Duration {
|
||||
return time.Duration(mins) * time.Minute
|
||||
}
|
||||
|
||||
// sessionToken extracts the session JWT as the "jwt" guard does: the
|
||||
// Authorization bearer header, then each session cookie in order.
|
||||
func sessionToken(r *http.Request) string {
|
||||
// SessionToken returns the session JWT the plugin's "jwt" guard reads from r:
|
||||
// the Authorization bearer header, then each cookie of SessionCookieNames in
|
||||
// order, trimmed, empty values skipped. It returns "" when r carries none.
|
||||
// A controller that builds its own guard passes SessionCookieNames() to
|
||||
// bouncer.NewJWTGuard, so the guard and SessionToken read the same token.
|
||||
func SessionToken(r *http.Request) string {
|
||||
if tokens := sessionTokens(r); len(tokens) > 0 {
|
||||
return tokens[0]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user