oauth

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 10, 2025 License: Apache-2.0 Imports: 14 Imported by: 0

README

OAuth Package

A flexible and secure OAuth 2.0 client implementation for Go applications, supporting multiple providers with PKCE (Proof Key for Code Exchange) for enhanced security.

Features

  • 🔐 Multiple OAuth Providers - GitHub, Google (coming soon), Apple (coming soon), Twitter (coming soon)
  • 🛡️ PKCE Support - Enhanced security with Proof Key for Code Exchange
  • ⚙️ Environment Configuration - Easy setup via environment variables
  • 🔄 Token Management - Automatic token handling with refresh support
  • 📦 Session Management - Built-in session store for OAuth state
  • 🎯 Type Safe - Strongly typed interfaces and configurations
  • 🧪 Well Tested - Comprehensive test coverage
  • 🏗️ Builder Pattern - Flexible configuration with custom prefixes

Installation

go get github.com/gobeaver/beaver-kit/oauth

Quick Start

Basic Usage
package main

import (
    "context"
    "log"
    
    "github.com/gobeaver/beaver-kit/oauth"
)

func main() {
    // Create OAuth configuration
    config := oauth.Config{
        Provider:     "github",
        ClientID:     "your_github_client_id",
        ClientSecret: "your_github_client_secret",
        RedirectURL:  "http://localhost:8080/callback",
    }
    
    // Initialize service
    service, err := oauth.New(config)
    if err != nil {
        log.Fatal(err)
    }
    
    // Use the service for OAuth flows
    // ... see examples below
}
Environment Configuration

Configure via environment variables with the BEAVER_OAUTH_ prefix:

# OAuth Provider Configuration
export BEAVER_OAUTH_PROVIDER=github
export BEAVER_OAUTH_CLIENT_ID=your_client_id
export BEAVER_OAUTH_CLIENT_SECRET=your_client_secret
export BEAVER_OAUTH_REDIRECT_URL=http://localhost:8080/callback

# Optional Configuration
export BEAVER_OAUTH_SCOPES=read:user,user:email
export BEAVER_OAUTH_PKCE_ENABLED=true
export BEAVER_OAUTH_DEBUG=false

Load from environment:

import (
    "github.com/gobeaver/beaver-kit/config"
    "github.com/gobeaver/beaver-kit/oauth"
)

// Load configuration from environment
cfg := &oauth.Config{}
if err := config.LoadFromEnv(cfg); err != nil {
    log.Fatal(err)
}

// Initialize service
service, err := oauth.New(*cfg)
Custom Environment Prefix

Use a custom prefix for multi-tenant applications:

// Use custom prefix
cfg := &oauth.Config{}
if err := config.LoadFromEnv(cfg, config.WithPrefix("MYAPP_")); err != nil {
    log.Fatal(err)
}
// Now reads from MYAPP_OAUTH_CLIENT_ID, etc.

OAuth Flow Implementation

1. Generate Authorization URL
// Start OAuth flow
authURL, state, err := service.GenerateAuthURL("github", true) // true enables PKCE
if err != nil {
    log.Fatal(err)
}

// Store state in session for CSRF protection
// Redirect user to authURL
2. Handle OAuth Callback
func handleCallback(w http.ResponseWriter, r *http.Request) {
    // Handle the OAuth callback
    resp, err := service.HandleCallback(r, "github")
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }
    
    // Verify state matches (CSRF protection)
    if resp.State != storedState {
        http.Error(w, "Invalid state", http.StatusBadRequest)
        return
    }
    
    // Get user information
    userInfo, err := service.GetUserInfo(context.Background(), "github", resp.Token.AccessToken)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    
    // User is authenticated!
    log.Printf("User: %s (%s)", userInfo.Name, userInfo.Email)
}
3. Direct Provider Usage
// Use provider directly for more control
provider := oauth.NewGitHub(oauth.ProviderConfig{
    ClientID:     "your_client_id",
    ClientSecret: "your_client_secret",
    RedirectURL:  "http://localhost:8080/callback",
    Scopes:       []string{"read:user", "user:email"},
})

// Generate auth URL with PKCE
pkce, err := oauth.GeneratePKCEChallenge("S256")
if err != nil {
    log.Fatal(err)
}

authURL := provider.GetAuthURL("state_token", pkce)

// After callback, exchange code for token
token, err := provider.Exchange(context.Background(), "auth_code", pkce)
if err != nil {
    log.Fatal(err)
}

// Get user info
userInfo, err := provider.GetUserInfo(context.Background(), token.AccessToken)

PKCE (Proof Key for Code Exchange)

PKCE provides additional security for OAuth flows, especially important for public clients:

// Generate PKCE challenge
pkce, err := oauth.GeneratePKCEChallenge("S256") // or "plain"
if err != nil {
    log.Fatal(err)
}

// Include in authorization URL
authURL := provider.GetAuthURL(state, pkce)

// Include verifier when exchanging code
token, err := provider.Exchange(ctx, code, pkce)

Provider-Specific Features

GitHub Provider
provider := oauth.NewGitHub(oauth.ProviderConfig{
    ClientID:     "github_client_id",
    ClientSecret: "github_client_secret",
    RedirectURL:  "http://localhost:8080/callback/github",
    Scopes:       []string{"read:user", "user:email"},
})

// GitHub-specific features:
// - Automatic private email retrieval
// - No refresh token support (GitHub tokens don't expire)
// - PKCE support for enhanced security

Token Management

Caching Tokens
// Cache token for later use
err := service.CacheToken(userID, "github", token)

// Retrieve cached token
cachedToken, err := service.GetCachedToken(userID, "github")
if err != nil {
    // Token not found or expired
}

// Clear cached token
err = service.ClearCachedToken(userID, "github")
Token Refresh

For providers that support refresh tokens:

// Refresh access token
newToken, err := provider.RefreshToken(ctx, refreshToken)
if err != nil {
    if err == oauth.ErrNoRefreshToken {
        // Provider doesn't support refresh (e.g., GitHub)
    }
}

Error Handling

The package provides detailed error types for OAuth-specific errors:

// Handle OAuth errors
resp, err := service.HandleCallback(r, "github")
if err != nil {
    var oauthErr *oauth.OAuthError
    if errors.As(err, &oauthErr) {
        log.Printf("OAuth error: %s - %s", oauthErr.Code, oauthErr.Description)
        
        switch oauthErr.Code {
        case "access_denied":
            // User denied access
        case "invalid_grant":
            // Invalid authorization code
        }
    }
}

// Common errors
var (
    ErrInvalidState      // State parameter mismatch (CSRF)
    ErrProviderNotFound  // Unknown provider
    ErrNoRefreshToken    // Provider doesn't support refresh
    ErrSessionNotFound   // Session data not found
    ErrTokenExpired      // Access token expired
)

Configuration Options

Full Configuration
type Config struct {
    // OAuth provider (github, google, etc.)
    Provider string
    
    // OAuth app credentials
    ClientID     string
    ClientSecret string
    RedirectURL  string
    
    // Comma-separated scopes
    Scopes string
    
    // State generation and validation
    State          string
    StateGenerator string // "uuid", "secure", "custom"
    
    // PKCE settings
    PKCEEnabled bool
    PKCEMethod  string // "S256" or "plain"
    
    // Token caching
    TokenCacheDuration time.Duration
    
    // HTTP settings
    HTTPTimeout time.Duration
    
    // Debug mode
    Debug bool
    
    // Custom provider URLs
    AuthURL     string
    TokenURL    string
    UserInfoURL string
}
Provider Configuration
type ProviderConfig struct {
    ClientID     string
    ClientSecret string
    RedirectURL  string
    Scopes       []string
    
    // Optional: Override default URLs
    AuthURL     string
    TokenURL    string
    UserInfoURL string
    
    // Optional: Custom HTTP client
    HTTPClient HTTPClient
    
    // Provider-specific settings
    TeamID     string // Apple
    KeyID      string // Apple
    PrivateKey string // Apple
    APIVersion string // Twitter
}

Testing

The package includes comprehensive tests. To run tests:

go test ./oauth/...

Example test:

func TestOAuthFlow(t *testing.T) {
    // Create test provider
    provider := oauth.NewGitHub(oauth.ProviderConfig{
        ClientID:     "test_id",
        ClientSecret: "test_secret",
        RedirectURL:  "http://test.local/callback",
    })
    
    // Test auth URL generation
    authURL := provider.GetAuthURL("test_state", nil)
    assert.Contains(t, authURL, "client_id=test_id")
    
    // Test PKCE
    pkce, err := oauth.GeneratePKCEChallenge("S256")
    assert.NoError(t, err)
    assert.NotEmpty(t, pkce.Challenge)
}

Security Best Practices

  1. Always use PKCE when available, especially for public clients
  2. Validate state parameter to prevent CSRF attacks
  3. Use HTTPS in production for redirect URLs
  4. Store tokens securely - never in client-side storage
  5. Implement token rotation when refresh tokens are available
  6. Validate scopes returned by the provider
  7. Set appropriate timeouts for HTTP requests

Supported Providers

Provider Status Refresh Token PKCE Support Notes
GitHub ✅ Complete Tokens don't expire
Google 🚧 Coming Soon OpenID Connect
Apple 📋 Planned Requires additional config
Twitter 📋 Planned OAuth 2.0 support
Custom 📋 Planned Varies Varies Generic OAuth 2.0

Advanced Usage

Custom State Generator
// Implement custom state generator
type MyStateGenerator struct{}

func (g *MyStateGenerator) Generate() (string, error) {
    // Your custom implementation
    return "custom_state_" + uuid.New().String(), nil
}

// Use in service
service.SetStateGenerator(&MyStateGenerator{})
Custom Session Store
// Implement custom session store (e.g., Redis)
type RedisSessionStore struct {
    client *redis.Client
}

func (s *RedisSessionStore) Store(ctx context.Context, key string, data *oauth.SessionData) error {
    // Store in Redis
}

func (s *RedisSessionStore) Retrieve(ctx context.Context, key string) (*oauth.SessionData, error) {
    // Retrieve from Redis
}

func (s *RedisSessionStore) Delete(ctx context.Context, key string) error {
    // Delete from Redis
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This package is part of the Beaver Kit project and follows its licensing terms.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidConfig indicates invalid configuration
	ErrInvalidConfig = errors.New("invalid configuration")

	// ErrNotInitialized indicates the service hasn't been initialized
	ErrNotInitialized = errors.New("oauth service not initialized")

	// ErrProviderNotFound indicates the requested provider doesn't exist
	ErrProviderNotFound = errors.New("oauth provider not found")

	// ErrInvalidState indicates state parameter mismatch (CSRF protection)
	ErrInvalidState = errors.New("invalid state parameter")

	// ErrTokenExpired indicates the token has expired
	ErrTokenExpired = errors.New("token expired")

	// ErrNoRefreshToken indicates no refresh token is available
	ErrNoRefreshToken = errors.New("no refresh token available")

	// ErrPKCENotSupported indicates PKCE is not supported by provider
	ErrPKCENotSupported = errors.New("PKCE not supported by provider")

	// ErrSessionNotFound indicates session data not found
	ErrSessionNotFound = errors.New("session not found")

	// ErrInvalidCode indicates invalid authorization code
	ErrInvalidCode = errors.New("invalid authorization code")

	// ErrNetworkError indicates a network error occurred
	ErrNetworkError = errors.New("network error")

	// ErrInvalidResponse indicates invalid response from provider
	ErrInvalidResponse = errors.New("invalid response from provider")

	// ErrAccessDenied indicates user denied access
	ErrAccessDenied = errors.New("access denied by user")

	// ErrUnsupportedResponseType indicates unsupported response type
	ErrUnsupportedResponseType = errors.New("unsupported response type")

	// ErrInvalidScope indicates invalid or unauthorized scope
	ErrInvalidScope = errors.New("invalid scope")

	// ErrServerError indicates provider server error
	ErrServerError = errors.New("provider server error")

	// ErrTemporarilyUnavailable indicates service temporarily unavailable
	ErrTemporarilyUnavailable = errors.New("service temporarily unavailable")
)

Package-level errors

Functions

func Init

func Init(configs ...Config) error

Init initializes the global OAuth service instance

func IsPKCESupported

func IsPKCESupported(provider string) bool

IsPKCESupported checks if a provider supports PKCE based on provider name

func IsRetryable

func IsRetryable(err error) bool

IsRetryable checks if an error is retryable

func PKCEParams

func PKCEParams(pkce *PKCEChallenge) map[string]string

PKCEParams returns URL parameters for PKCE

func PKCETokenParams

func PKCETokenParams(pkce *PKCEChallenge) map[string]string

PKCETokenParams returns token exchange parameters for PKCE

func Reset

func Reset()

Reset clears the global instance (for testing)

func ValidatePKCEChallenge

func ValidatePKCEChallenge(verifier, challenge, method string) bool

ValidatePKCEChallenge validates that a verifier matches a challenge

Types

type AuthorizationRequest

type AuthorizationRequest struct {
	State         string
	PKCEChallenge *PKCEChallenge
	RedirectURL   string
	Scopes        []string
	ExtraParams   map[string]string
}

AuthorizationRequest represents an OAuth authorization request

type AuthorizationResponse

type AuthorizationResponse struct {
	Code  string
	State string
	Error string
}

AuthorizationResponse represents the response from an OAuth authorization

type Builder

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

Builder pattern for custom prefixes

func WithPrefix

func WithPrefix(prefix string) *Builder

WithPrefix creates a new Builder with the specified prefix

func (*Builder) Init

func (b *Builder) Init() error

Init initializes the OAuth service with the builder's prefix

func (*Builder) New

func (b *Builder) New() (*Service, error)

New creates a new OAuth service instance with the builder's prefix

type Config

type Config struct {
	// Provider specifies the OAuth provider (google, github, apple, twitter, custom)
	Provider string `env:"OAUTH_PROVIDER,default:google"`

	// ClientID is the OAuth application's client ID
	ClientID string `env:"OAUTH_CLIENT_ID,required"`

	// ClientSecret is the OAuth application's client secret
	ClientSecret string `env:"OAUTH_CLIENT_SECRET,required"`

	// RedirectURL is the callback URL after authentication
	RedirectURL string `env:"OAUTH_REDIRECT_URL,required"`

	// Scopes is a comma-separated list of OAuth scopes
	Scopes string `env:"OAUTH_SCOPES,default:openid,profile,email"`

	// State is the default state parameter for CSRF protection
	State string `env:"OAUTH_STATE"`

	// StateGenerator defines how to generate state tokens (uuid, secure, custom)
	StateGenerator string `env:"OAUTH_STATE_GENERATOR,default:secure"`

	// PKCEEnabled enables PKCE flow for enhanced security
	PKCEEnabled bool `env:"OAUTH_PKCE_ENABLED,default:true"`

	// PKCEMethod is the PKCE challenge method (S256 or plain)
	PKCEMethod string `env:"OAUTH_PKCE_METHOD,default:S256"`

	// TokenCacheDuration is how long to cache tokens
	TokenCacheDuration time.Duration `env:"OAUTH_TOKEN_CACHE_DURATION,default:1h"`

	// HTTPTimeout is the timeout for HTTP requests
	HTTPTimeout time.Duration `env:"OAUTH_HTTP_TIMEOUT,default:30s"`

	// Debug enables debug logging
	Debug bool `env:"OAUTH_DEBUG,default:false"`

	// Custom provider configuration (for generic OAuth2 providers)
	AuthURL     string `env:"OAUTH_AUTH_URL"`
	TokenURL    string `env:"OAUTH_TOKEN_URL"`
	UserInfoURL string `env:"OAUTH_USERINFO_URL"`

	// Provider-specific configurations
	AppleTeamID     string `env:"OAUTH_APPLE_TEAM_ID"`
	AppleKeyID      string `env:"OAUTH_APPLE_KEY_ID"`
	ApplePrivateKey string `env:"OAUTH_APPLE_PRIVATE_KEY"`

	// Twitter API version (1.1 or 2)
	TwitterAPIVersion string `env:"OAUTH_TWITTER_API_VERSION,default:2"`
}

Config defines the OAuth service configuration

func GetConfig

func GetConfig(opts ...config.LoadOptions) (*Config, error)

GetConfig returns config loaded from environment with optional LoadOptions

type GitHubProvider

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

GitHubProvider implements OAuth provider for GitHub

func NewGitHub

func NewGitHub(config ProviderConfig) *GitHubProvider

NewGitHub creates a new GitHub OAuth provider

func (*GitHubProvider) Exchange

func (g *GitHubProvider) Exchange(ctx context.Context, code string, pkce *PKCEChallenge) (*Token, error)

Exchange exchanges an authorization code for tokens

func (*GitHubProvider) GetAuthURL

func (g *GitHubProvider) GetAuthURL(state string, pkce *PKCEChallenge) string

GetAuthURL returns the authorization URL with PKCE parameters if enabled

func (*GitHubProvider) GetUserInfo

func (g *GitHubProvider) GetUserInfo(ctx context.Context, accessToken string) (*UserInfo, error)

GetUserInfo retrieves user information using the access token

func (*GitHubProvider) Name

func (g *GitHubProvider) Name() string

Name returns the provider name

func (*GitHubProvider) RefreshToken

func (g *GitHubProvider) RefreshToken(ctx context.Context, refreshToken string) (*Token, error)

RefreshToken refreshes the access token

func (*GitHubProvider) RevokeToken

func (g *GitHubProvider) RevokeToken(ctx context.Context, token string) error

RevokeToken revokes the access token

func (*GitHubProvider) SetHTTPClient

func (g *GitHubProvider) SetHTTPClient(client HTTPClient)

SetHTTPClient sets a custom HTTP client

func (*GitHubProvider) SupportsPKCE

func (g *GitHubProvider) SupportsPKCE() bool

SupportsPKCE indicates if the provider supports PKCE

func (*GitHubProvider) SupportsRefresh

func (g *GitHubProvider) SupportsRefresh() bool

SupportsRefresh indicates if the provider supports token refresh

func (*GitHubProvider) ValidateConfig

func (g *GitHubProvider) ValidateConfig() error

ValidateConfig validates the provider configuration

type GitHubUser

type GitHubUser struct {
	ID              int64  `json:"id"`
	Login           string `json:"login"`
	Email           string `json:"email"`
	Name            string `json:"name"`
	AvatarURL       string `json:"avatar_url"`
	Bio             string `json:"bio"`
	Company         string `json:"company"`
	Location        string `json:"location"`
	Blog            string `json:"blog"`
	TwitterUsername string `json:"twitter_username"`
}

GitHubUser represents the user data returned by GitHub

type HTTPClient

type HTTPClient interface {
	Do(req *http.Request) (*http.Response, error)
}

HTTPClient interface for mocking in tests

type MemorySessionStore

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

MemorySessionStore implements SessionStore with in-memory storage

func NewMemorySessionStore

func NewMemorySessionStore(ttl time.Duration) *MemorySessionStore

func (*MemorySessionStore) Delete

func (s *MemorySessionStore) Delete(ctx context.Context, key string) error

func (*MemorySessionStore) Retrieve

func (s *MemorySessionStore) Retrieve(ctx context.Context, key string) (*SessionData, error)

func (*MemorySessionStore) Store

func (s *MemorySessionStore) Store(ctx context.Context, key string, data *SessionData) error

type MemoryTokenStore

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

MemoryTokenStore implements TokenStore with in-memory storage

func NewMemoryTokenStore

func NewMemoryTokenStore(ttl time.Duration) *MemoryTokenStore

func (*MemoryTokenStore) Delete

func (s *MemoryTokenStore) Delete(ctx context.Context, key string) error

func (*MemoryTokenStore) Retrieve

func (s *MemoryTokenStore) Retrieve(ctx context.Context, key string) (*Token, error)

func (*MemoryTokenStore) Store

func (s *MemoryTokenStore) Store(ctx context.Context, key string, token *Token) error

type OAuthError

type OAuthError struct {
	Code        string // OAuth error code (e.g., "invalid_request")
	Description string // Human-readable error description
	URI         string // Optional URI with error details
	Provider    string // Provider where error occurred
	Err         error  // Underlying error
}

OAuthError represents a detailed OAuth error

func NewOAuthError

func NewOAuthError(provider, code, description string) *OAuthError

NewOAuthError creates a new OAuth error

func ParseOAuthError

func ParseOAuthError(provider string, code, description, uri string) *OAuthError

ParseOAuthError parses OAuth error from response

func WrapOAuthError

func WrapOAuthError(provider string, err error) *OAuthError

WrapOAuthError wraps an error with OAuth context

func (*OAuthError) Error

func (e *OAuthError) Error() string

Error implements the error interface

func (*OAuthError) Is

func (e *OAuthError) Is(target error) bool

Is checks if the error matches a target error

func (*OAuthError) Unwrap

func (e *OAuthError) Unwrap() error

Unwrap returns the underlying error

type PKCEChallenge

type PKCEChallenge struct {
	Verifier        string `json:"verifier"`
	Challenge       string `json:"challenge"`
	ChallengeMethod string `json:"challenge_method"`
}

PKCEChallenge represents PKCE challenge parameters

func GeneratePKCEChallenge

func GeneratePKCEChallenge(method string) (*PKCEChallenge, error)

GeneratePKCEChallenge generates a PKCE challenge with verifier and challenge

type Provider

type Provider interface {
	// GetAuthURL returns the authorization URL with PKCE parameters if enabled
	GetAuthURL(state string, pkce *PKCEChallenge) string

	// Exchange exchanges an authorization code for tokens
	Exchange(ctx context.Context, code string, pkce *PKCEChallenge) (*Token, error)

	// RefreshToken refreshes an access token using a refresh token
	RefreshToken(ctx context.Context, refreshToken string) (*Token, error)

	// GetUserInfo retrieves user information using an access token
	GetUserInfo(ctx context.Context, accessToken string) (*UserInfo, error)

	// Name returns the provider name
	Name() string

	// SupportsRefresh indicates if the provider supports token refresh
	SupportsRefresh() bool

	// SupportsPKCE indicates if the provider supports PKCE
	SupportsPKCE() bool
}

Provider defines the interface that all OAuth providers must implement

func NewAppleProvider

func NewAppleProvider(config ProviderConfig) (Provider, error)

func NewCustomProvider

func NewCustomProvider(config ProviderConfig) (Provider, error)

func NewGitHubProvider

func NewGitHubProvider(config ProviderConfig) (Provider, error)

func NewGoogleProvider

func NewGoogleProvider(config ProviderConfig) (Provider, error)

func NewTwitterProvider

func NewTwitterProvider(config ProviderConfig) (Provider, error)

type ProviderConfig

type ProviderConfig struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string
	Scopes       []string
	AuthURL      string
	TokenURL     string
	UserInfoURL  string
	HTTPClient   HTTPClient
	Debug        bool

	// Apple-specific
	TeamID     string
	KeyID      string
	PrivateKey string

	// Twitter-specific
	APIVersion string
}

ProviderConfig represents configuration for a specific OAuth provider

type SecureStateGenerator

type SecureStateGenerator struct{}

SecureStateGenerator generates cryptographically secure state tokens

func (*SecureStateGenerator) Generate

func (g *SecureStateGenerator) Generate() (string, error)

type Service

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

Service is the main OAuth service

func GetService

func GetService() *Service

GetService returns the global OAuth service instance

func New

func New(cfg Config) (*Service, error)

New creates a new OAuth service instance

func OAuth

func OAuth() *Service

OAuth is an alias for GetService()

func (*Service) Config

func (s *Service) Config() Config

Config returns the service configuration

func (*Service) Exchange

func (s *Service) Exchange(ctx context.Context, code, state string) (*Token, error)

Exchange exchanges an authorization code for tokens

func (*Service) GetAuthURL

func (s *Service) GetAuthURL(ctx context.Context) (string, error)

GetAuthURL generates an authorization URL

func (*Service) GetUserInfo

func (s *Service) GetUserInfo(ctx context.Context, accessToken string) (*UserInfo, error)

GetUserInfo retrieves user information

func (*Service) Provider

func (s *Service) Provider() Provider

Provider returns the current provider

func (*Service) RefreshToken

func (s *Service) RefreshToken(ctx context.Context, refreshToken string) (*Token, error)

RefreshToken refreshes an access token

func (*Service) ValidateState

func (s *Service) ValidateState(ctx context.Context, state string) error

ValidateState validates the state parameter for CSRF protection

type SessionData

type SessionData struct {
	State         string         `json:"state"`
	PKCEChallenge *PKCEChallenge `json:"pkce_challenge,omitempty"`
	CreatedAt     time.Time      `json:"created_at"`
	ExpiresAt     time.Time      `json:"expires_at"`
	Provider      string         `json:"provider"`
}

SessionData represents OAuth session data that can be stored

func (*SessionData) IsExpired

func (s *SessionData) IsExpired() bool

IsExpired checks if the session data is expired

type SessionStore

type SessionStore interface {
	// Store stores session data with a key
	Store(ctx context.Context, key string, data *SessionData) error

	// Retrieve gets session data by key
	Retrieve(ctx context.Context, key string) (*SessionData, error)

	// Delete removes session data by key
	Delete(ctx context.Context, key string) error
}

SessionStore interface for storing OAuth session data

type StateGenerator

type StateGenerator interface {
	Generate() (string, error)
}

StateGenerator interface for generating state tokens

type Token

type Token struct {
	AccessToken  string    `json:"access_token"`
	TokenType    string    `json:"token_type"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	ExpiresIn    int       `json:"expires_in,omitempty"`
	ExpiresAt    time.Time `json:"expires_at,omitempty"`
	IDToken      string    `json:"id_token,omitempty"` // For OpenID Connect
	Scope        string    `json:"scope,omitempty"`
}

Token represents OAuth tokens

func (*Token) IsExpired

func (t *Token) IsExpired() bool

IsExpired checks if the token is expired

func (*Token) TimeUntilExpiry

func (t *Token) TimeUntilExpiry() time.Duration

TimeUntilExpiry returns the duration until the token expires

type TokenStore

type TokenStore interface {
	// Store stores a token with a key
	Store(ctx context.Context, key string, token *Token) error

	// Retrieve gets a token by key
	Retrieve(ctx context.Context, key string) (*Token, error)

	// Delete removes a token by key
	Delete(ctx context.Context, key string) error
}

TokenStore interface for caching OAuth tokens

type UUIDStateGenerator

type UUIDStateGenerator struct{}

UUIDStateGenerator generates UUID-based state tokens

func (*UUIDStateGenerator) Generate

func (g *UUIDStateGenerator) Generate() (string, error)

type UserInfo

type UserInfo struct {
	ID            string                 `json:"id"`
	Email         string                 `json:"email"`
	EmailVerified bool                   `json:"email_verified"`
	Name          string                 `json:"name"`
	FirstName     string                 `json:"first_name"`
	LastName      string                 `json:"last_name"`
	Picture       string                 `json:"picture"`
	Locale        string                 `json:"locale"`
	Provider      string                 `json:"provider"`
	Raw           map[string]interface{} `json:"raw"` // Raw response from provider
}

UserInfo represents user information from OAuth providers

Jump to

Keyboard shortcuts

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