### Device Authorization Flow with `Config.DeviceAuth` and `Config.DeviceAccessToken` Source: https://context7.com/golang/oauth2/llms.txt Implement RFC 8628 for devices without a browser. Use `DeviceAuth` to get user codes and `DeviceAccessToken` to poll for approval. ```go ctx := context.Background() conf := &oauth2.Config{ ClientID: "your-client-id", Scopes: []string{"read:user"}, Endpoint: endpoints.GitHub, // GitHub supports DeviceAuthURL } // Step 1: Request device and user codes. da, err := conf.DeviceAuth(ctx) if err != nil { log.Fatal(err) } fmt.Printf("Visit %s and enter code: %s\n", da.VerificationURI, da.UserCode) // Visit https://github.com/login/device and enter code: ABCD-1234 // Step 2: Poll for the token (blocks until approved, denied, or expired). tok, err := conf.DeviceAccessToken(ctx, da) if err != nil { log.Fatal(err) } fmt.Println("Access token:", tok.AccessToken) ``` -------------------------------- ### Client Credentials Flow with `clientcredentials.Config` Source: https://context7.com/golang/oauth2/llms.txt Implement the 2-legged OAuth 2.0 client credentials grant (RFC 6749 §4.4) for server-to-server authentication. Use `Token` to fetch a token or `Client` to get a self-refreshing HTTP client. ```go import ( "context" "fmt" "log" "golang.org/x/oauth2/clientcredentials" ) func main() { ctx := context.Background() conf := &clientcredentials.Config{ ClientID: "service-client-id", ClientSecret: "service-client-secret", TokenURL: "https://provider.example.com/oauth2/token", Scopes: []string{"api.read", "api.write"}, // Optional: pass extra parameters to the token endpoint. EndpointParams: url.Values{"audience": {"https://api.example.com"}}, } // Fetch a token directly. tok, err := conf.Token(ctx) if err != nil { log.Fatal(err) } fmt.Println("Access token:", tok.AccessToken) // Or get a self-refreshing HTTP client. client := conf.Client(ctx) resp, err := client.Get("https://api.example.com/v1/data") if err != nil { log.Fatal(err) } defer resp.Body.Close() } ``` -------------------------------- ### Obtain Reusable TokenSource Source: https://context7.com/golang/oauth2/llms.txt Get an `oauth2.TokenSource` that caches tokens and refreshes them automatically. Prefer this for finer control or when passing credentials to third-party libraries. ```go ctx := context.Background() tok, _ := conf.Exchange(ctx, "auth-code") // Create a reusable, thread-safe token source. ts := conf.TokenSource(ctx, tok) // Retrieve a valid token (refreshes automatically when expired). validTok, err := ts.Token() if err != nil { log.Fatal(err) } fmt.Println(validTok.AccessToken) // Pass to NewClient directly. httpClient := oauth2.NewClient(ctx, ts) httpClient.Get("https://api.example.com/resource") ``` -------------------------------- ### Complete 3-legged OAuth 2.0 Flow with PKCE Source: https://context7.com/golang/oauth2/llms.txt This snippet demonstrates the full authorization code flow, including generating a PKCE verifier, building the auth URL, exchanging the code for a token, and using a self-refreshing HTTP client. Ensure you have a callback server running to receive the code. ```go import ( "context" "fmt" "log" "golang.org/x/oauth2" "golang.org/x/oauth2/endpoints" ) func main() { ctx := context.Background() conf := &oauth2.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURL: "http://localhost:8080/callback", Scopes: []string{"read:user", "repo"}, Endpoint: endpoints.GitHub, } // Step 1: Generate PKCE verifier and redirect the user. verifier := oauth2.GenerateVerifier() state := "random-csrf-state" authURL := conf.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(verifier)) fmt.Println("Open this URL in a browser:", authURL) // Step 2: After the user grants access, receive the code from the callback. var code string fmt.Scan(&code) // Step 3: Exchange code for token (includes PKCE verifier). tok, err := conf.Exchange(ctx, code, oauth2.VerifierOption(verifier)) if err != nil { log.Fatal(err) } fmt.Println("Access token:", tok.AccessToken) fmt.Println("Expiry:", tok.Expiry) // Step 4: Use a self-refreshing HTTP client. client := conf.Client(ctx, tok) resp, err := client.Get("https://api.github.com/user") if err != nil { log.Fatal(err) } defer resp.Body.Close() // resp.Body contains the API response; token is refreshed automatically. } ``` -------------------------------- ### Build Authorization Redirect URL with PKCE and Custom Params Source: https://context7.com/golang/oauth2/llms.txt This snippet shows how to construct the authorization server's consent page URL using `AuthCodeURL`. It includes options for offline access, forcing re-approval, PKCE, and injecting custom URL parameters like `login_hint`. ```go conf := &oauth2.Config{ ClientID: "client-id", ClientSecret: "client-secret", RedirectURL: "https://myapp.example.com/oauth/callback", Scopes: []string{"openid", "email", "profile"}, Endpoint: oauth2.Endpoint{ AuthURL: "https://accounts.google.com/o/oauth2/auth", TokenURL: "https://oauth2.googleapis.com/token", }, } verifier := oauth2.GenerateVerifier() url := conf.AuthCodeURL( "unique-state-value", oauth2.AccessTypeOffline, oauth2.ApprovalForce, oauth2.S256ChallengeOption(verifier), oauth2.SetAuthURLParam("login_hint", "user@example.example.com"), ) // Redirect browser to `url` fmt.Println(url) // https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=client-id // &code_challenge=...&code_challenge_method=S256&login_hint=user%40example.com // &prompt=consent&redirect_uri=...&response_type=code&scope=openid+email+profile&state=unique-state-value ``` -------------------------------- ### Manage OAuth2 Tokens with `oauth2.Token` Source: https://context7.com/golang/oauth2/llms.txt Demonstrates creating, validating, and setting Authorization headers using the `oauth2.Token` struct. Use `Valid()` to check token status and `SetAuthHeader()` for HTTP requests. ```go tok := &oauth2.Token{ AccessToken: "ya29.access-token", TokenType: "Bearer", RefreshToken: "1//refresh-token", Expiry: time.Now().Add(time.Hour), } fmt.Println(tok.Valid()) // true fmt.Println(tok.Type()) // Bearer // Manually set Authorization header. req, _ := http.NewRequest("GET", "https://api.example.com/me", nil) tok.SetAuthHeader(req) fmt.Println(req.Header.Get("Authorization")) // Bearer ya29.access-token // Access extra fields returned by the token endpoint. tokWithExtra := tok.WithExtra(map[string]any{"id_token": "eyJ..."}) fmt.Println(tokWithExtra.Extra("id_token")) // eyJ... ``` -------------------------------- ### PKCE Support with `GenerateVerifier`, `S256ChallengeOption`, `VerifierOption` Source: https://context7.com/golang/oauth2/llms.txt Integrate PKCE (RFC 7636) to protect against CSRF and authorization code interception. Generate a verifier, pass its challenge to `AuthCodeURL`, and the verifier itself to `Exchange`. ```go // Generate a fresh verifier for each authorization request. verifier := oauth2.GenerateVerifier() // 43-char base64url string // Build the auth URL with the S256 challenge derived from the verifier. authURL := conf.AuthCodeURL("state", oauth2.S256ChallengeOption(verifier)) fmt.Println(authURL) // ...&code_challenge=BASE64URL(SHA256(verifier))&code_challenge_method=S256... // After receiving the code, exchange it with the verifier. tok, err := conf.Exchange(ctx, "received-code", oauth2.VerifierOption(verifier)) if err != nil { log.Fatal(err) } fmt.Println(tok.AccessToken) // Manual challenge computation if needed: challenge := oauth2.S256ChallengeFromVerifier(verifier) fmt.Println("challenge:", challenge) ``` -------------------------------- ### Google Service Account from JSON with `google.JWTConfigFromJSON` Source: https://context7.com/golang/oauth2/llms.txt Parses Google service account JSON key files to create a JWT configuration. This is useful for authenticating as a service account when the key is available as a file. ```go import ( "context" "log" "os" "golang.org/x/oauth2/google" ) func main() { ctx := context.Background() // Service account key (downloaded from Cloud Console). keyJSON, err := os.ReadFile("service-account.json") if err != nil { log.Fatal(err) } jwtConf, err := google.JWTConfigFromJSON(keyJSON, "https://www.googleapis.com/auth/spreadsheets", "https://www.googleapis.com/auth/drive.readonly", ) if err != nil { log.Fatal(err) } client := jwtConf.Client(ctx) resp, err := client.Get("https://sheets.googleapis.com/v4/spreadsheets/SPREADSHEET_ID") if err != nil { log.Fatal(err) } defer resp.Body.Close() } ``` -------------------------------- ### Google Compute Engine Token Source with `google.ComputeTokenSource` Source: https://context7.com/golang/oauth2/llms.txt Fetches OAuth 2.0 tokens from the GCE instance metadata server. Use this when your code runs on Google Cloud compute platforms like GCE, GKE, or Cloud Run. ```go import ( "context" "log" "golang.org/x/oauth2" "golang.org/x/oauth2/google" ) func main() { ctx := context.Background() // Use the "default" service account attached to the GCE instance. ts := google.ComputeTokenSource("", "https://www.googleapis.com/auth/cloud-platform") client := oauth2.NewClient(ctx, ts) resp, err := client.Get("https://storage.googleapis.com/storage/v1/b?project=my-project") if err != nil { log.Fatal(err) } defer resp.Body.Close() } ``` -------------------------------- ### Authorization Handler for 3-Legged OAuth in Non-Browser Environments Source: https://context7.com/golang/oauth2/llms.txt Supports 3-legged OAuth flows in non-browser environments by providing a custom `AuthorizationHandler` function. This handler presents the authorization URL to the user and reads the authorization code from stdin. Supports PKCE for enhanced security. ```go import ( "context" "fmt" "golang.org/x/oauth2" "golang.org/x/oauth2/authhandler" "golang.org/x/oauth2/endpoints" ) func main() { ctx := context.Background() conf := &oauth2.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURL: "urn:ietf:wg:oauth:2.0:oob", Scopes: []string{"https://www.googleapis.com/auth/drive.readonly"}, Endpoint: endpoints.Google, } // CLI handler: print URL and read the code from stdin. handler := func(authCodeURL string) (string, string, error) { fmt.Println("Open this URL:", authCodeURL) fmt.Print("Enter the authorization code: ") var code string fmt.Scan(&code) return code, "state-value", nil } // With PKCE support. verifier := oauth2.GenerateVerifier() pkce := &authhandler.PKCEParams{ Challenge: oauth2.S256ChallengeFromVerifier(verifier), ChallengeMethod: "S256", Verifier: verifier, } ts := authhandler.TokenSourceWithPKCE(ctx, conf, "state-value", handler, pkce) tok, err := ts.Token() if err != nil { panic(err) } fmt.Println("Got token:", tok.AccessToken[:10], "...") } ``` -------------------------------- ### JWT Bearer Flow with `jwt.Config` Source: https://context7.com/golang/oauth2/llms.txt Use this for 2-legged OAuth 2.0 flows, such as with Google service accounts. Ensure your private key file is accessible and the configuration details are correct. ```go import ( "context" "log" "os" "golang.org/x/oauth2/jwt" ) func main() { ctx := context.Background() privateKey, err := os.ReadFile("service-account-key.pem") if err != nil { log.Fatal(err) } conf := &jwt.Config{ Email: "my-service-account@project.iam.gserviceaccount.com", PrivateKey: privateKey, PrivateKeyID: "key-id-from-json", Scopes: []string{"https://www.googleapis.com/auth/cloud-platform"}, TokenURL: "https://oauth2.googleapis.com/token", // Subject: "user@domain.com", // set for domain-wide delegation } client := conf.Client(ctx) resp, err := client.Get("https://storage.googleapis.com/storage/v1/b?project=my-project") if err != nil { log.Fatal(err) } defer resp.Body.Close() // JWT is signed and sent automatically; token is cached and refreshed. } ``` -------------------------------- ### Inject Custom HTTP Client with Context Source: https://context7.com/golang/oauth2/llms.txt Store a custom *http.Client in the context using oauth2.HTTPClient as the key to control the transport for token acquisition. This does not affect outbound API requests. Ensure the custom client is configured with appropriate timeouts and TLS settings. ```go import ( "context" "crypto/tls" "net/http" "time" "golang.org/x/oauth2" ) // Custom HTTP client with a short timeout and relaxed TLS (e.g., for testing). customHTTPClient := &http.Client{ Timeout: 5 * time.Second, Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, }, } ctx := context.WithValue(context.Background(), oauth2.HTTPClient, customHTTPClient) // All token endpoint calls within this context use customHTTPClient. tok, err := conf.Exchange(ctx, "auth-code") if err != nil { // transport error or token error } _ = tok ``` -------------------------------- ### Obtain Self-Refreshing HTTP Client Source: https://context7.com/golang/oauth2/llms.txt Create an `http.Client` that automatically adds Bearer tokens and refreshes them when expired using the stored refresh token. ```go ctx := context.Background() // tok was previously obtained via Exchange and may be persisted/loaded. tok := &oauth2.Token{ AccessToken: "ya29.existing-access-token", RefreshToken: "1//existing-refresh-token", Expiry: time.Now().Add(-time.Hour), // already expired — will auto-refresh } client := conf.Client(ctx, tok) // All requests through this client automatically carry a valid Bearer token. resp, err := client.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json") if err != nil { log.Fatal(err) } deferr resp.Body.Close() // Authorization: Bearer is set transparently ``` -------------------------------- ### Google Application Default Credentials with `google.FindDefaultCredentials` Source: https://context7.com/golang/oauth2/llms.txt This function automatically finds the best available credentials for Google Cloud services. It checks environment variables, gcloud configuration, and the metadata server. ```go import ( "context" "fmt" "log" "golang.org/x/oauth2/google" ) func main() { ctx := context.Background() // FindDefaultCredentials searches in order: // 1. GOOGLE_APPLICATION_CREDENTIALS env var // 2. gcloud application_default_credentials.json // 3. GCE/GKE metadata server creds, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform", ) if err != nil { log.Fatal(err) } fmt.Println("Project:", creds.ProjectID) ud, _ := creds.GetUniverseDomain() fmt.Println("Universe domain:", ud) // googleapis.com client := oauth2.NewClient(ctx, creds.TokenSource) resp, err := client.Get("https://storage.googleapis.com/storage/v1/b?project=" + creds.ProjectID) if err != nil { log.Fatal(err) } defer resp.Body.Close() } ``` -------------------------------- ### Provider Endpoints for Popular OAuth 2.0 Services Source: https://context7.com/golang/oauth2/llms.txt Provides pre-defined `oauth2.Endpoint` constants for numerous popular OAuth 2.0 providers. Includes factory functions for creating endpoints for tenant-parameterized providers like Azure AD, AWS Cognito, and Shopify. ```go import ( "golang.org/x/oauth2" "golang.org/x/oauth2/endpoints" ) // Static endpoints (constants for well-known providers). var ( githubEndpoint = endpoints.GitHub // AuthURL + TokenURL + DeviceAuthURL googleEndpoint = endpoints.Google slackEndpoint = endpoints.Slack spotifyEndpoint = endpoints.Spotify discordEndpoint = endpoints.Discord ) // Parameterized endpoints (tenant/domain-specific). azureEndpoint := endpoints.AzureAD("my-tenant-id") // https://login.microsoftonline.com/my-tenant-id/oauth2/v2.0/authorize azureB2CEndpoint := endpoints.AzureADB2CEndpoint("mytenant", "B2C_1_SignUpSignIn") cognitoEndpoint := endpoints.AWSCognito("https://mypool.auth.us-east-1.amazoncognito.com") shopifyEndpoint := endpoints.Shopify("mystore.myshopify.com") asgardeoEndpoint := endpoints.AsgardeoEndpoint("my-org") // Use with oauth2.Config: conf := &oauth2.Config{ ClientID: "client-id", ClientSecret: "client-secret", Scopes: []string{"user:email"}, Endpoint: endpoints.GitHub, } _ = conf ``` -------------------------------- ### Token Caching Wrappers Source: https://context7.com/golang/oauth2/llms.txt Wrap a `TokenSource` with `ReuseTokenSource` or `ReuseTokenSourceWithExpiry` to cache tokens in memory, reducing calls to the underlying source. `ReuseTokenSourceWithExpiry` allows specifying an early-expiry buffer. ```go // Wrap a custom TokenSource to add in-memory caching. type myTokenSource struct{} func (m myTokenSource) Token() (*oauth2.Token, error) { // Fetch token from a secrets manager or custom endpoint. return &oauth2.Token{ AccessToken: "fetched-token", Expiry: time.Now().Add(time.Hour), }, nil } var ts oauth2.TokenSource = myTokenSource{} // Cache it; refresh 30 seconds before expiry. cachedTS := oauth2.ReuseTokenSourceWithExpiry(nil, ts, 30*time.Second) tok, err := cachedTS.Token() // calls myTokenSource.Token() tok2, _ := cachedTS.Token() // returns cached token, no call to myTokenSource fmt.Println(tok.AccessToken == tok2.AccessToken) // true ``` -------------------------------- ### Exchange Authorization Code for Token Source: https://context7.com/golang/oauth2/llms.txt Use `Exchange` to trade an authorization code for an OAuth2 token. Pass `VerifierOption` if PKCE was used during `AuthCodeURL`. ```go ctx := context.Background() tok, err := conf.Exchange(ctx, "auth-code-from-callback", oauth2.VerifierOption(verifier)) if err != nil { if rErr, ok := err.(*oauth2.RetrieveError); ok { fmt.Println("HTTP status:", rErr.Response.Status) fmt.Println("Error code:", rErr.ErrorCode) fmt.Println("Description:", rErr.ErrorDescription) } log.Fatal(err) } fmt.Println("Access token:", tok.AccessToken) fmt.Println("Refresh token:", tok.RefreshToken) fmt.Println("Expiry:", tok.Expiry) fmt.Println("Valid:", tok.Valid()) // Access token: ya29.xxx // Refresh token: 1//xxx // Expiry: 2024-03-15 12:00:00 +0000 UTC // Valid: true ``` -------------------------------- ### PKCE Support Source: https://context7.com/golang/oauth2/llms.txt PKCE (RFC 7636) enhances security by preventing CSRF and authorization code interception. Generate a verifier for each flow, pass the challenge to `AuthCodeURL`, and the verifier to `Exchange`. ```APIDOC ## PKCE Support ### Description PKCE (Proof Key for Code Exchange, RFC 7636) protects against CSRF and authorization code interception. Generate a verifier once per flow; pass the challenge to `AuthCodeURL` and the verifier to `Exchange`. ### Usage ```go // Generate a fresh verifier for each authorization request. verifier := oauth2.GenerateVerifier() // 43-char base64url string // Build the auth URL with the S256 challenge derived from the verifier. authURL := conf.AuthCodeURL("state", oauth2.S256ChallengeOption(verifier)) fmt.Println(authURL) // ...&code_challenge=BASE64URL(SHA256(verifier))&code_challenge_method=S256... // After receiving the code, exchange it with the verifier. tok, err := conf.Exchange(ctx, "received-code", oauth2.VerifierOption(verifier)) if err != nil { log.Fatal(err) } fmt.Println(tok.AccessToken) // Manual challenge computation if needed: challenge := oauth2.S256ChallengeFromVerifier(verifier) fmt.Println("challenge:", challenge)``` ``` -------------------------------- ### Device Authorization Flow Source: https://context7.com/golang/oauth2/llms.txt Implements RFC 8628 for devices without browsers. `DeviceAuth` obtains user and device codes, while `DeviceAccessToken` polls for token approval. ```APIDOC ## Device Authorization Flow ### Description Implements RFC 8628 for devices without a browser. `DeviceAuth` retrieves a user code and verification URI; the user enters the code on another device. `DeviceAccessToken` polls until the user approves or the code expires. ### Usage ```go ctx := context.Background() conf := &oauth2.Config{ ClientID: "your-client-id", Scopes: []string{"read:user"}, Endpoint: endpoints.GitHub, // GitHub supports DeviceAuthURL } // Step 1: Request device and user codes. da, err := conf.DeviceAuth(ctx) if err != nil { log.Fatal(err) } fmt.Printf("Visit %s and enter code: %s\n", da.VerificationURI, da.UserCode) // Visit https://github.com/login/device and enter code: ABCD-1234 // Step 2: Poll for the token (blocks until approved, denied, or expired). tok, err := conf.DeviceAccessToken(ctx, da) if err != nil { log.Fatal(err) } fmt.Println("Access token:", tok.AccessToken)``` ``` -------------------------------- ### Client Credentials Flow Source: https://context7.com/golang/oauth2/llms.txt The `clientcredentials` sub-package implements the OAuth 2.0 client credentials grant (RFC 6749 §4.4) for server-to-server authentication. ```APIDOC ## Client Credentials Flow ### Description The `clientcredentials` sub-package implements the 2-legged OAuth 2.0 "client credentials" grant (RFC 6749 §4.4) for server-to-server authentication where no user is involved. ### Usage ```go import ( "context" "fmt" "log" "golang.org/x/oauth2/clientcredentials" ) func main() { ctx := context.Background() conf := &clientcredentials.Config{ ClientID: "service-client-id", ClientSecret: "service-client-secret", TokenURL: "https://provider.example.com/oauth2/token", Scopes: []string{"api.read", "api.write"}, // Optional: pass extra parameters to the token endpoint. EndpointParams: url.Values{"audience": {"https://api.example.com"}}, } // Fetch a token directly. tok, err := conf.Token(ctx) if err != nil { log.Fatal(err) } fmt.Println("Access token:", tok.AccessToken) // Or get a self-refreshing HTTP client. client := conf.Client(ctx) resp, err := client.Get("https://api.example.com/v1/data") if err != nil { log.Fatal(err) } defer resp.Body.Close() }``` ``` -------------------------------- ### oauth2.Config.Client Source: https://context7.com/golang/oauth2/llms.txt `Config.Client` returns an `*http.Client` that automatically attaches Bearer tokens to all requests and silently refreshes the access token when it expires using the stored refresh token. ```APIDOC ## oauth2.Config.Client — Obtain a self-refreshing HTTP client ### Description Returns an `*http.Client` that automatically attaches Bearer tokens to all requests and silently refreshes the access token when it expires using the stored refresh token. ### Method `Client` ### Parameters - `ctx` (context.Context) - The context for the request. - `tok` (*oauth2.Token) - The token to use for authentication. ### Request Example ```go ctx := context.Background() // tok was previously obtained via Exchange and may be persisted/loaded. tok := &oauth2.Token{ AccessToken: "ya29.existing-access-token", RefreshToken: "1//existing-refresh-token", Expiry: time.Now().Add(-time.Hour), // already expired — will auto-refresh } client := conf.Client(ctx, tok) // All requests through this client automatically carry a valid Bearer token. resp, err := client.Get("https://www.googleapis.com/oauth2/v1/userinfo?alt=json") if err != nil { log.Fatal(err) } defer resp.Body.Close() // Authorization: Bearer is set transparently ``` ### Response - `*http.Client` - An HTTP client configured with automatic token attachment and refresh capabilities. ``` -------------------------------- ### Provider Endpoints Source: https://context7.com/golang/oauth2/llms.txt Provides pre-defined `oauth2.Endpoint` constants for numerous popular OAuth 2.0 providers and factory functions for creating endpoints for tenant-parameterized providers. ```APIDOC ## Provider Endpoints — `endpoints` package The `endpoints` package provides pre-defined `oauth2.Endpoint` constants for 40+ popular OAuth 2.0 providers, plus factory functions for tenant-parameterized providers like Azure AD, AWS Cognito, and Shopify. ### Static Endpoints Constants for well-known providers: - `endpoints.GitHub` - `endpoints.Google` - `endpoints.Slack` - `endpoints.Spotify` - `endpoints.Discord` ### Parameterized Endpoints Factory functions for tenant/domain-specific providers: - `endpoints.AzureAD(tenantID string)`: Returns an endpoint for Azure AD. Example: `https://login.microsoftonline.com/my-tenant-id/oauth2/v2.0/authorize` - `endpoints.AzureADB2CEndpoint(tenant string, policy string)`: Returns an endpoint for Azure AD B2C. - `endpoints.AWSCognito(domain string)`: Returns an endpoint for AWS Cognito. Example: `https://mypool.auth.us-east-1.amazoncognito.com` - `endpoints.Shopify(storeDomain string)`: Returns an endpoint for Shopify. Example: `mystore.myshopify.com` - `endpoints.AsgardeoEndpoint(org string)`: Returns an endpoint for Asgardeo. ### Usage with `oauth2.Config` ```go import ( "golang.org/x/oauth2" "golang.org/x/oauth2/endpoints" ) // Using a static endpoint confStatic := &oauth2.Config{ ClientID: "client-id", ClientSecret: "client-secret", Scopes: []string{"user:email"}, Endpoint: endpoints.GitHub, } _ = confStatic // Using a parameterized endpoint confAzure := &oauth2.Config{ ClientID: "client-id", ClientSecret: "client-secret", Scopes: []string{"user:email"}, Endpoint: endpoints.AzureAD("my-tenant-id"), } _ = confAzure ``` ``` -------------------------------- ### oauth2.Config.Exchange Source: https://context7.com/golang/oauth2/llms.txt `Exchange` performs the token endpoint request, trading the authorization code for an `*oauth2.Token` that contains `AccessToken`, `RefreshToken`, and `Expiry`. Pass `VerifierOption(verifier)` when PKCE was used in `AuthCodeURL`. ```APIDOC ## oauth2.Config.Exchange — Exchange authorization code for a token ### Description Performs the token endpoint request, trading the authorization code for an `*oauth2.Token` that contains `AccessToken`, `RefreshToken`, and `Expiry`. Pass `VerifierOption(verifier)` when PKCE was used in `AuthCodeURL`. ### Method `Exchange` ### Parameters - `ctx` (context.Context) - The context for the request. - `code` (string) - The authorization code received from the callback. - `opts` (oauth2.AuthCodeOption...) - Options for the exchange, such as `VerifierOption`. ### Request Example ```go ctx := context.Background() tok, err := conf.Exchange(ctx, "auth-code-from-callback", oauth2.VerifierOption(verifier)) if err != nil { // Handle error } ``` ### Response #### Success Response - `*oauth2.Token` - An object containing the access token, refresh token, and expiry information. #### Response Example ```go fmt.Println("Access token:", tok.AccessToken) fmt.Println("Refresh token:", tok.RefreshToken) fmt.Println("Expiry:", tok.Expiry) fmt.Println("Valid:", tok.Valid()) // Access token: ya29.xxx // Refresh token: 1//xxx // Expiry: 2024-03-15 12:00:00 +0000 UTC // Valid: true ``` #### Error Handling If an error occurs during the exchange, it might be a `*oauth2.RetrieveError` containing details about the HTTP response and the specific error code and description. ``` -------------------------------- ### oauth2.StaticTokenSource Source: https://context7.com/golang/oauth2/llms.txt `StaticTokenSource` wraps a single `*Token` and always returns it unchanged. Suitable for short-lived tokens or integration tests. ```APIDOC ## oauth2.StaticTokenSource — Non-refreshing token source ### Description Wraps a single `*Token` and always returns it unchanged. This is suitable for short-lived tokens or integration tests. ### Method `StaticTokenSource` ### Parameters - `token` (*oauth2.Token) - The static token to be returned. ### Request Example ```go tok := &oauth2.Token{AccessToken: "static-token-value"} ts := oauth2.StaticTokenSource(tok) client := oauth2.NewClient(context.Background(), ts) resp, err := client.Get("https://api.example.com/data") if err != nil { log.Fatal(err) } defer resp.Body.Close() ``` ### Response - `oauth2.TokenSource` - A token source that always returns the provided static token. ``` -------------------------------- ### Static Non-Refreshing TokenSource Source: https://context7.com/golang/oauth2/llms.txt Use `StaticTokenSource` to wrap a single token that is always returned unchanged. Suitable for short-lived tokens or integration tests. ```go tok := &oauth2.Token{AccessToken: "static-token-value"} ts := oauth2.StaticTokenSource(tok) client := oauth2.NewClient(context.Background(), ts) resp, err := client.Get("https://api.example.com/data") if err != nil { log.Fatal(err) } deferr resp.Body.Close() ``` -------------------------------- ### Authorization Handler Source: https://context7.com/golang/oauth2/llms.txt Supports 3-legged OAuth flows in non-browser environments by accepting a custom `AuthorizationHandler` function to manage the user interaction for obtaining an authorization code. ```APIDOC ## Authorization Handler — `authhandler.TokenSource` The `authhandler` sub-package supports 3-legged OAuth flows in non-browser environments (CLIs, desktop apps) by accepting a custom `AuthorizationHandler` function that presents the URL to the user and returns the authorization code. ### Method Signature `authhandler.TokenSourceWithPKCE(ctx context.Context, conf *oauth2.Config, state string, handler authhandler.AuthorizationHandler, pkce *authhandler.PKCEParams) oauth2.TokenSource` ### Parameters - `ctx` (context.Context): The context for the request. - `conf` (*oauth2.Config): The OAuth2 configuration. - `state` (string): An opaque value used to maintain state between the request and the callback. - `handler` (authhandler.AuthorizationHandler): A function that handles the user authorization process. - Signature: `func(authCodeURL string) (code string, state string, err error)` - `pkce` (*authhandler.PKCEParams): Parameters for Proof Key for Code Exchange (PKCE). - `Challenge` (string): The code challenge. - `ChallengeMethod` (string): The method used to generate the challenge (e.g., "S256"). - `Verifier` (string): The code verifier. ### Example Usage ```go import ( "context" "fmt" "golang.org/x/oauth2" "golang.org/x/oauth2/authhandler" "golang.org/x/oauth2/endpoints" ) func main() { ctx := context.Background() conf := &oauth2.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURL: "urn:ietf:wg:oauth:2.0:oob", Scopes: []string{"https://www.googleapis.com/auth/drive.readonly"}, Endpoint: endpoints.Google, } // CLI handler: print URL and read the code from stdin. handler := func(authCodeURL string) (string, string, error) { fmt.Println("Open this URL:", authCodeURL) fmt.Print("Enter the authorization code: ") var code string fmt.Scan(&code) return code, "state-value", nil } // With PKCE support. verifier := oauth2.GenerateVerifier() pkce := &authhandler.PKCEParams{ Challenge: oauth2.S256ChallengeFromVerifier(verifier), ChallengeMethod: "S256", Verifier: verifier, } ts := authhandler.TokenSourceWithPKCE(ctx, conf, "state-value", handler, pkce) tok, err := ts.Token() if err != nil { panic(err) } fmt.Println("Got token:", tok.AccessToken[:10], "...") } ``` ``` -------------------------------- ### oauth2.Token Source: https://context7.com/golang/oauth2/llms.txt `Token` holds OAuth 2.0 credentials. The `Valid()` method checks for presence and expiry, `Extra()` retrieves provider-specific fields, and `SetAuthHeader()` manually configures the Authorization header on an `*http.Request`. ```APIDOC ## oauth2.Token ### Description `Token` holds the OAuth 2.0 credentials returned by the server. `Valid()` checks both presence and expiry. `Extra()` retrieves provider-specific fields from the raw server response. `SetAuthHeader()` manually sets the Authorization header on an `*http.Request`. ### Usage ```go tok := &oauth2.Token{ AccessToken: "ya29.access-token", TokenType: "Bearer", RefreshToken: "1//refresh-token", Expiry: time.Now().Add(time.Hour), } fmt.Println(tok.Valid()) // true fmt.Println(tok.Type()) // Bearer // Manually set Authorization header. req, _ := http.NewRequest("GET", "https://api.example.com/me", nil) tok.SetAuthHeader(req) fmt.Println(req.Header.Get("Authorization")) // Bearer ya29.access-token // Access extra fields returned by the token endpoint. tokWithExtra := tok.WithExtra(map[string]any{"id_token": "eyJ..."}) fmt.Println(tokWithExtra.Extra("id_token")) // eyJ...``` ``` -------------------------------- ### Custom HTTP Transport with `oauth2.Transport` Source: https://context7.com/golang/oauth2/llms.txt Implement `http.RoundTripper` to automatically add OAuth2 Authorization headers to HTTP requests. Wrap an optional base `RoundTripper` for custom request handling. ```go ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: "my-token"}) transport := &oauth2.Transport{ Source: ts, Base: http.DefaultTransport, // optional; defaults to http.DefaultTransport } client := &http.Client{Transport: transport} resp, err := client.Get("https://api.example.com/resource") if err != nil { log.Fatal(err) } def resp.Body.Close() // Authorization: Bearer my-token is automatically set on all requests ``` -------------------------------- ### Google Credential Downscoping with NewTokenSource Source: https://context7.com/golang/oauth2/llms.txt Restricts an existing token's permissions using IAM Credential Access Boundaries for Google Cloud Storage. Requires root credentials with broad permissions to create a downscoped token with limited access. ```go import ( "context" "fmt" "log" "golang.org/x/oauth2/google" "golang.org/x/oauth2/google/downscope" ) func main() { ctx := context.Background() // Root credential with broad permissions. rootCreds, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform", ) if err != nil { log.Fatal(err) } // Downscoped token: read-only access to a single bucket. downscopedTS, err := downscope.NewTokenSource(ctx, downscope.DownscopingConfig{ RootSource: rootCreds.TokenSource, Rules: []downscope.AccessBoundaryRule{ { AvailableResource: "//storage.googleapis.com/projects/_/buckets/my-bucket", AvailablePermissions: []string{"inRole:roles/storage.objectViewer"}, Condition: &downscope.AvailabilityCondition{ Expression: `resource.name.startsWith("projects/_/buckets/my-bucket/objects/public/")`, Title: "public-objects-only", }, }, }, }) if err != nil { log.Fatal(err) } tok, err := downscopedTS.Token() if err != nil { log.Fatal(err) } fmt.Println("Downscoped token:", tok.AccessToken[:20], "...") // This token can ONLY read objects under gs://my-bucket/public/ } ``` -------------------------------- ### oauth2.Config.TokenSource Source: https://context7.com/golang/oauth2/llms.txt `TokenSource` returns an `oauth2.TokenSource` that caches the current token and refreshes it automatically. Prefer this over `Client` when you need finer control, or when passing credentials to third-party libraries that accept a `TokenSource`. ```APIDOC ## oauth2.Config.TokenSource — Obtain a reusable `TokenSource` ### Description Returns an `oauth2.TokenSource` that caches the current token and refreshes it automatically. This is preferred over `Client` for finer control or when passing credentials to third-party libraries that accept a `TokenSource`. ### Method `TokenSource` ### Parameters - `ctx` (context.Context) - The context for the request. - `tok` (*oauth2.Token) - The initial token. ### Request Example ```go ctx := context.Background() tok, _ := conf.Exchange(ctx, "auth-code") // Create a reusable, thread-safe token source. ts := conf.TokenSource(ctx, tok) // Retrieve a valid token (refreshes automatically when expired). validTok, err := ts.Token() if err != nil { log.Fatal(err) } fmt.Println(validTok.AccessToken) // Pass to NewClient directly. httpClient := oauth2.NewClient(ctx, ts) httpClient.Get("https://api.example.com/resource") ``` ### Response - `oauth2.TokenSource` - A token source that manages token caching and automatic refreshing. ``` -------------------------------- ### oauth2.ReuseTokenSource / oauth2.ReuseTokenSourceWithExpiry Source: https://context7.com/golang/oauth2/llms.txt `ReuseTokenSource` wraps any `TokenSource` to cache the token in memory and only call the underlying source when the cached token has expired. `ReuseTokenSourceWithExpiry` adds a configurable early-expiry buffer. ```APIDOC ## oauth2.ReuseTokenSource / oauth2.ReuseTokenSourceWithExpiry — Token caching wrappers ### Description Wraps any `TokenSource` to cache the token in memory and only call the underlying source when the cached token has expired. `ReuseTokenSourceWithExpiry` adds a configurable early-expiry buffer. ### Method `ReuseTokenSource` and `ReuseTokenSourceWithExpiry` ### Parameters - `ctx` (context.Context) - The context for the request (optional for `ReuseTokenSourceWithExpiry`). - `parent` (oauth2.TokenSource) - The underlying token source to wrap. - `expiryBuffer` (time.Duration) - The buffer before expiry to trigger a refresh (for `ReuseTokenSourceWithExpiry`). ### Request Example ```go // Wrap a custom TokenSource to add in-memory caching. type myTokenSource struct{} func (m myTokenSource) Token() (*oauth2.Token, error) { // Fetch token from a secrets manager or custom endpoint. return &oauth2.Token{ AccessToken: "fetched-token", Expiry: time.Now().Add(time.Hour), }, nil } var ts oauth2.TokenSource = myTokenSource{} // Cache it; refresh 30 seconds before expiry. cachedTS := oauth2.ReuseTokenSourceWithExpiry(nil, ts, 30*time.Second) tok, err := cachedTS.Token() // calls myTokenSource.Token() tok2, _ := cachedTS.Token() // returns cached token, no call to myTokenSource fmt.Println(tok.AccessToken == tok2.AccessToken) // true ``` ### Response - `oauth2.TokenSource` - A token source that caches tokens and refreshes them automatically based on expiry. ``` -------------------------------- ### oauth2.Transport Source: https://context7.com/golang/oauth2/llms.txt `Transport` implements `http.RoundTripper` to inject the Authorization header into requests using a configured `TokenSource`. It can optionally wrap a base `RoundTripper`. ```APIDOC ## oauth2.Transport ### Description `Transport` implements `http.RoundTripper` and injects the Authorization header into every request using the configured `TokenSource`. It wraps an optional base `RoundTripper`. ### Usage ```go ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: "my-token"}) transport := &oauth2.Transport{ Source: ts, Base: http.DefaultTransport, // optional; defaults to http.DefaultTransport } client := &http.Client{Transport: transport} resp, err := client.Get("https://api.example.com/resource") if err != nil { log.Fatal(err) } defer resp.Body.Close() // Authorization: Bearer my-token is automatically set on all requests``` ``` -------------------------------- ### Google Credential Downscoping Source: https://context7.com/golang/oauth2/llms.txt Restricts an existing token's permissions using IAM Credential Access Boundaries. This is useful for limiting access to specific resources like Cloud Storage buckets and operations. ```APIDOC ## Google Credential Downscoping — `google/downscope.NewTokenSource` The `downscope` sub-package restricts an existing token's permissions using IAM Credential Access Boundaries, limiting access to specific Cloud Storage buckets and operations. Only Google Cloud Storage is supported. ### Method Signature `downscope.NewTokenSource(ctx context.Context, config downscope.DownscopingConfig) (*oauth2.TokenSource, error)` ### Parameters - `ctx` (context.Context): The context for the request. - `config` (downscope.DownscopingConfig): Configuration for downscoping. - `RootSource` (oauth2.TokenSource): The root token source with broad permissions. - `Rules` ([]downscope.AccessBoundaryRule): A list of rules to apply for downscoping. - `AvailableResource` (string): The resource to which access is being limited. - `AvailablePermissions` ([]string): The permissions available for the resource. - `Condition` (*downscope.AvailabilityCondition): An optional condition to further restrict access. - `Expression` (string): The condition expression. - `Title` (string): The title of the condition. ### Example Usage ```go import ( "context" "fmt" "log" "golang.org/x/oauth2/google" "golang.org/x/oauth2/google/downscope" ) func main() { ctx := context.Background() // Root credential with broad permissions. rootCreds, err := google.FindDefaultCredentials(ctx, "https://www.googleapis.com/auth/cloud-platform", ) if err != nil { log.Fatal(err) } // Downscoped token: read-only access to a single bucket. downscopedTS, err := downscope.NewTokenSource(ctx, downscope.DownscopingConfig{ RootSource: rootCreds.TokenSource, Rules: []downscope.AccessBoundaryRule{ { AvailableResource: "//storage.googleapis.com/projects/_/buckets/my-bucket", AvailablePermissions: []string{"inRole:roles/storage.objectViewer"}, Condition: &downscope.AvailabilityCondition{ Expression: `resource.name.startsWith(\"projects/_/buckets/my-bucket/objects/public/\")`, Title: "public-objects-only", }, }, }, }) if err != nil { log.Fatal(err) } tok, err := downscopedTS.Token() if err != nil { log.Fatal(err) } fmt.Println("Downscoped token:", tok.AccessToken[:20], "...") // This token can ONLY read objects under gs://my-bucket/public/ } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.