@@ -26,7 +26,8 @@ var ErrInvalidToken = errors.New("invalid token")
2626
2727// A TokenVerifier checks the validity of a bearer token, and extracts information
2828// from it. If verification fails, it should return an error that unwraps to ErrInvalidToken.
29- type TokenVerifier func (ctx context.Context , token string ) (* TokenInfo , error )
29+ // The HTTP request is provided in case verifying the token involves checking it.
30+ type TokenVerifier func (ctx context.Context , token string , req * http.Request ) (* TokenInfo , error )
3031
3132// RequireBearerTokenOptions are options for [RequireBearerToken].
3233type RequireBearerTokenOptions struct {
@@ -52,14 +53,16 @@ func TokenInfoFromContext(ctx context.Context) *TokenInfo {
5253// If verification succeeds, the [TokenInfo] is added to the request's context and the request proceeds.
5354// If verification fails, the request fails with a 401 Unauthenticated, and the WWW-Authenticate header
5455// is populated to enable [protected resource metadata].
56+ //
57+
5558//
5659// [protected resource metadata]: https://datatracker.ietf.org/doc/rfc9728
5760func RequireBearerToken (verifier TokenVerifier , opts * RequireBearerTokenOptions ) func (http.Handler ) http.Handler {
5861 // Based on typescript-sdk/src/server/auth/middleware/bearerAuth.ts.
5962
6063 return func (handler http.Handler ) http.Handler {
6164 return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
62- tokenInfo , errmsg , code := verify (r . Context () , verifier , opts , r . Header . Get ( "Authorization" ) )
65+ tokenInfo , errmsg , code := verify (r , verifier , opts )
6366 if code != 0 {
6467 if code == http .StatusUnauthorized || code == http .StatusForbidden {
6568 if opts != nil && opts .ResourceMetadataURL != "" {
@@ -75,15 +78,16 @@ func RequireBearerToken(verifier TokenVerifier, opts *RequireBearerTokenOptions)
7578 }
7679}
7780
78- func verify (ctx context. Context , verifier TokenVerifier , opts * RequireBearerTokenOptions , authHeader string ) (_ * TokenInfo , errmsg string , code int ) {
81+ func verify (req * http. Request , verifier TokenVerifier , opts * RequireBearerTokenOptions ) (_ * TokenInfo , errmsg string , code int ) {
7982 // Extract bearer token.
83+ authHeader := req .Header .Get ("Authorization" )
8084 fields := strings .Fields (authHeader )
8185 if len (fields ) != 2 || strings .ToLower (fields [0 ]) != "bearer" {
8286 return nil , "no bearer token" , http .StatusUnauthorized
8387 }
8488
8589 // Verify the token and get information from it.
86- tokenInfo , err := verifier (ctx , fields [1 ])
90+ tokenInfo , err := verifier (req . Context () , fields [1 ], req )
8791 if err != nil {
8892 if errors .Is (err , ErrInvalidToken ) {
8993 return nil , err .Error (), http .StatusUnauthorized
0 commit comments