Skip to content

Commit 71e2449

Browse files
authored
feat: add cache headers (#2817)
1 parent 4682afa commit 71e2449

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

session/handler.go

+7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package session
22

33
import (
4+
"fmt"
45
"net/http"
56
"strconv"
67

@@ -178,6 +179,11 @@ type toSession struct {
178179
func (h *Handler) whoami(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
179180
s, err := h.r.SessionManager().FetchFromRequest(r.Context(), r)
180181
if err != nil {
182+
// We cache errors where no session was found.
183+
if noSess := new(ErrNoActiveSessionFound); errors.As(err, &noSess) && noSess.credentialsMissing {
184+
w.Header().Set("X-Ory-Cache-Until", "180")
185+
}
186+
181187
h.r.Audit().WithRequest(r).WithError(err).Info("No valid session cookie found.")
182188
h.r.Writer().WriteError(w, r, herodot.ErrUnauthorized.WithWrap(err).WithReasonf("No valid session cookie found."))
183189
return
@@ -200,6 +206,7 @@ func (h *Handler) whoami(w http.ResponseWriter, r *http.Request, ps httprouter.P
200206

201207
// Set userId as the X-Kratos-Authenticated-Identity-Id header.
202208
w.Header().Set("X-Kratos-Authenticated-Identity-Id", s.Identity.ID.String())
209+
w.Header().Set("X-Ory-Cache-Until", fmt.Sprintf("%d", s.ExpiresAt.Unix()))
203210

204211
if err := h.r.SessionManager().RefreshCookie(r.Context(), w, r, s); err != nil {
205212
h.r.Audit().WithRequest(r).WithError(err).Info("Could not re-issue cookie.")

session/handler_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ func TestSessionWhoAmI(t *testing.T) {
150150
res, err := client.Get(ts.URL + RouteWhoami)
151151
require.NoError(t, err)
152152
assertNoCSRFCookieInResponse(t, ts, client, res) // Test that no CSRF cookie is ever set here.
153+
assert.NotEmpty(t, res.Header.Get("X-Ory-Session-Expires-At"))
153154

154155
// Set cookie
155156
reg.CSRFHandler().IgnorePath("/set")
@@ -174,6 +175,7 @@ func TestSessionWhoAmI(t *testing.T) {
174175

175176
assert.EqualValues(t, http.StatusOK, res.StatusCode)
176177
assert.NotEmpty(t, res.Header.Get("X-Kratos-Authenticated-Identity-Id"))
178+
assert.NotEmpty(t, res.Header.Get("X-Ory-Session-Expires-At"))
177179

178180
assert.Empty(t, gjson.GetBytes(body, "identity.credentials"))
179181
assert.Equal(t, "mp", gjson.GetBytes(body, "identity.metadata_public.public").String(), "%s", body)

session/manager.go

+10
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import (
1515
// ErrNoActiveSessionFound is returned when no active cookie session could be found in the request.
1616
type ErrNoActiveSessionFound struct {
1717
*herodot.DefaultError `json:"error"`
18+
19+
// True when the request had no credentials in it.
20+
credentialsMissing bool
1821
}
1922

2023
// NewErrNoActiveSessionFound creates a new ErrNoActiveSessionFound
@@ -24,6 +27,13 @@ func NewErrNoActiveSessionFound() *ErrNoActiveSessionFound {
2427
}
2528
}
2629

30+
// NewErrNoCredentialsForSession creates a new NewErrNoCredentialsForSession
31+
func NewErrNoCredentialsForSession() *ErrNoActiveSessionFound {
32+
e := NewErrNoActiveSessionFound()
33+
e.credentialsMissing = true
34+
return e
35+
}
36+
2737
func (e *ErrNoActiveSessionFound) EnhanceJSONError() interface{} {
2838
return e
2939
}

session/manager_http.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ func (s *ManagerHTTP) extractToken(r *http.Request) string {
185185
func (s *ManagerHTTP) FetchFromRequest(ctx context.Context, r *http.Request) (*Session, error) {
186186
token := s.extractToken(r)
187187
if token == "" {
188-
return nil, errors.WithStack(NewErrNoActiveSessionFound())
188+
return nil, errors.WithStack(NewErrNoCredentialsForSession())
189189
}
190190

191191
se, err := s.r.SessionPersister().GetSessionByToken(ctx, token, ExpandEverything)

0 commit comments

Comments
 (0)