oauth

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package oauth provides OAuth 2.0 discovery, token exchange, and refresh functionality.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateState

func GenerateState() (string, error)

GenerateState returns a cryptographically secure OAuth state parameter. The state is 22 characters (16 random bytes, base64url-encoded without padding).

Use this to prevent CSRF attacks on the OAuth flow. Store the state before redirecting to the authorization endpoint, and verify it matches when handling the callback.

Example:

state, err := oauth.GenerateState()
if err != nil {
    return err
}
session.Set("oauth_state", state)
authURL := fmt.Sprintf("%s?state=%s", baseURL, state)
// Later, in the callback handler:
if r.URL.Query().Get("state") != session.Get("oauth_state") {
    return errors.New("state mismatch")
}

Types

type Config

type Config struct {
	Issuer                string   `json:"issuer"`
	AuthorizationEndpoint string   `json:"authorization_endpoint"`
	TokenEndpoint         string   `json:"token_endpoint"`
	RegistrationEndpoint  string   `json:"registration_endpoint,omitempty"`
	ScopesSupported       []string `json:"scopes_supported,omitempty"`
}

Config represents an OAuth 2.0 server configuration from discovery.

type Discoverer

type Discoverer struct {
	// contains filtered or unexported fields
}

Discoverer fetches OAuth 2.0 server configuration from discovery endpoints.

func NewDiscoverer

func NewDiscoverer(httpClient *http.Client) *Discoverer

NewDiscoverer creates a Discoverer with the given HTTP client. If httpClient is nil, http.DefaultClient is used.

func (*Discoverer) Discover

func (d *Discoverer) Discover(ctx context.Context, baseURL string) (*Config, error)

Discover fetches OAuth configuration from the well-known discovery endpoint. The baseURL should be the OAuth server's base URL (e.g., "https://launchpad.37signals.com").

type ExchangeRequest

type ExchangeRequest struct {
	TokenEndpoint string
	Code          string
	RedirectURI   string
	ClientID      string
	ClientSecret  string
	CodeVerifier  string

	// UseLegacyFormat uses Launchpad's non-standard token format:
	// type=web_server instead of grant_type=authorization_code
	UseLegacyFormat bool
}

ExchangeRequest contains parameters for exchanging an authorization code for tokens.

type Exchanger

type Exchanger struct {
	// contains filtered or unexported fields
}

Exchanger handles OAuth 2.0 token exchange and refresh operations.

func NewExchanger

func NewExchanger(httpClient *http.Client) *Exchanger

NewExchanger creates an Exchanger with the given HTTP client. If httpClient is nil, http.DefaultClient is used.

func (*Exchanger) Exchange

func (e *Exchanger) Exchange(ctx context.Context, req ExchangeRequest) (*Token, error)

Exchange exchanges an authorization code for access and refresh tokens.

func (*Exchanger) Refresh

func (e *Exchanger) Refresh(ctx context.Context, req RefreshRequest) (*Token, error)

Refresh exchanges a refresh token for a new access token.

type PKCE

type PKCE struct {
	// Verifier is the cryptographically random code_verifier to send during token exchange.
	Verifier string
	// Challenge is the SHA256 hash of the verifier, base64url-encoded, to send during authorization.
	Challenge string
}

PKCE holds a code verifier and its corresponding challenge for OAuth 2.0 PKCE flow.

func GeneratePKCE

func GeneratePKCE() (*PKCE, error)

GeneratePKCE returns a cryptographically secure PKCE code verifier and its SHA256 code challenge. The verifier is 43 characters (32 random bytes, base64url-encoded without padding). The challenge is the base64url-encoded SHA256 hash of the verifier.

Use the Challenge with code_challenge_method=S256 in the authorization request, and the Verifier in the token exchange request.

Example:

pkce, err := oauth.GeneratePKCE()
if err != nil {
    return err
}
authURL := fmt.Sprintf("%s?code_challenge=%s&code_challenge_method=S256", baseURL, pkce.Challenge)
// Later, during token exchange:
token, err := oauth.Exchange(ctx, code, pkce.Verifier, ...)

type RefreshRequest

type RefreshRequest struct {
	TokenEndpoint string
	RefreshToken  string
	ClientID      string
	ClientSecret  string

	// UseLegacyFormat uses Launchpad's non-standard token format:
	// type=refresh instead of grant_type=refresh_token
	UseLegacyFormat bool
}

RefreshRequest contains parameters for refreshing an access token.

type Token

type Token struct {
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	TokenType    string    `json:"token_type"`
	ExpiresIn    int       `json:"expires_in,omitempty"`
	ExpiresAt    time.Time `json:"-"`
	Scope        string    `json:"scope,omitempty"`
}

Token represents an OAuth 2.0 access token response.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL