Skip to content

Commit c3af4e3

Browse files
committed
fix: using caching for jwks
1 parent cb6de2d commit c3af4e3

File tree

3 files changed

+33
-20
lines changed

3 files changed

+33
-20
lines changed

recipe/thirdparty/providers/apple.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"strings"
2424
"time"
2525

26-
"github.com/MicahParks/keyfunc"
2726
"github.com/golang-jwt/jwt/v4"
2827
"github.com/supertokens/supertokens-golang/recipe/thirdparty/api"
2928
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
@@ -177,16 +176,8 @@ func verifyAndGetClaimsAppleIdToken(idToken string, clientId string) (jwt.MapCla
177176
// Get the JWKS URL.
178177
jwksURL := "https://appleid.apple.com/auth/keys"
179178

180-
// Create the keyfunc options. Refresh the JWKS every hour and log errors.
181-
options := keyfunc.Options{
182-
// https://github.com/supertokens/supertokens-golang/issues/155
183-
// This causes a leak as the pointer to JWKS would be held in the goroutine and
184-
// also results in compounding refresh requests
185-
// RefreshInterval: time.Hour,
186-
}
187-
188179
// Create the JWKS from the resource at the given URL.
189-
jwks, err := keyfunc.Get(jwksURL, options)
180+
jwks, err := getJWKSFromURL(jwksURL)
190181
if err != nil {
191182
return claims, err
192183
}

recipe/thirdparty/providers/googleWorkspaces.go

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"errors"
2020
"strings"
2121

22-
"github.com/MicahParks/keyfunc"
2322
"github.com/golang-jwt/jwt/v4"
2423
"github.com/supertokens/supertokens-golang/recipe/thirdparty/api"
2524
"github.com/supertokens/supertokens-golang/recipe/thirdparty/tpmodels"
@@ -139,16 +138,8 @@ func verifyAndGetClaims(idToken string, clientId string) (jwt.MapClaims, error)
139138
// Get the JWKS URL.
140139
jwksURL := "https://www.googleapis.com/oauth2/v3/certs"
141140

142-
// Create the keyfunc options. Refresh the JWKS every hour and log errors.
143-
options := keyfunc.Options{
144-
// https://github.com/supertokens/supertokens-golang/issues/155
145-
// This causes a leak as the pointer to JWKS would be held in the goroutine and
146-
// also results in compounding refresh requests
147-
// RefreshInterval: time.Hour,
148-
}
149-
150141
// Create the JWKS from the resource at the given URL.
151-
jwks, err := keyfunc.Get(jwksURL, options)
142+
jwks, err := getJWKSFromURL(jwksURL)
152143
if err != nil {
153144
return claims, err
154145
}

recipe/thirdparty/providers/utils.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ import (
2121
"fmt"
2222
"io/ioutil"
2323
"net/http"
24+
"sync"
25+
"time"
26+
27+
"github.com/MicahParks/keyfunc"
2428
)
2529

2630
func doGetRequest(req *http.Request) (interface{}, error) {
@@ -47,3 +51,30 @@ func doGetRequest(req *http.Request) (interface{}, error) {
4751
}
4852
return result, nil
4953
}
54+
55+
var jwksKeys = map[string]*keyfunc.JWKS{}
56+
var jwksKeysLock = sync.Mutex{}
57+
58+
func getJWKSFromURL(url string) (*keyfunc.JWKS, error) {
59+
if jwks, ok := jwksKeys[url]; ok {
60+
return jwks, nil
61+
}
62+
63+
jwksKeysLock.Lock()
64+
defer jwksKeysLock.Unlock()
65+
66+
// Check again to see if it was added while we were waiting for the lock
67+
if jwks, ok := jwksKeys[url]; ok {
68+
return jwks, nil
69+
}
70+
71+
options := keyfunc.Options{
72+
RefreshInterval: time.Hour,
73+
}
74+
jwks, err := keyfunc.Get(url, options)
75+
if err != nil {
76+
return nil, err
77+
}
78+
jwksKeys[url] = jwks
79+
return jwks, nil
80+
}

0 commit comments

Comments
 (0)