oauth2

package
v1.0.4 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package oauth2 provides a pluggable OAuth2/OIDC provider abstraction for social login. Each provider implements the Provider interface to handle authorization URL generation, token exchange, and user info retrieval. Implementations include GoogleProvider (with PKCE S256), GitHubProvider, and FacebookProvider.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type FacebookProvider

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

FacebookProvider implements the Provider interface for Facebook OAuth2. Uses PKCE S256 code challenge for authorization code exchange security.

func NewFacebookProvider

func NewFacebookProvider(clientID, clientSecret, redirectURI string) *FacebookProvider

NewFacebookProvider creates a Facebook OAuth2 provider with the given credentials and redirect URI.

func (*FacebookProvider) AuthURL

func (f *FacebookProvider) AuthURL(state, nonce, codeChallenge string) string

AuthURL returns the Facebook OAuth2 authorization URL with PKCE S256 code challenge. The nonce parameter is ignored as Facebook does not support OIDC.

func (*FacebookProvider) Exchange

func (f *FacebookProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)

Exchange trades an authorization code for an access token via Facebook's token endpoint, using the PKCE code verifier for validation.

func (*FacebookProvider) Name

func (f *FacebookProvider) Name() string

Name returns "facebook".

func (*FacebookProvider) UserInfo

func (f *FacebookProvider) UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)

UserInfo fetches the authenticated user's profile from Facebook's Graph API.

type GitHubProvider

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

GitHubProvider implements the Provider interface for GitHub OAuth2. Uses PKCE S256 code challenge for authorization code exchange security.

func NewGitHubProvider

func NewGitHubProvider(clientID, clientSecret, redirectURI string) *GitHubProvider

NewGitHubProvider creates a GitHub OAuth2 provider with the given credentials and redirect URI.

func (*GitHubProvider) AuthURL

func (g *GitHubProvider) AuthURL(state, nonce, codeChallenge string) string

AuthURL returns the GitHub OAuth2 authorization URL with PKCE S256 code challenge. The nonce parameter is ignored as GitHub does not support OIDC.

func (*GitHubProvider) Exchange

func (g *GitHubProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)

Exchange trades an authorization code for an access token via GitHub's token endpoint, using the PKCE code verifier for validation.

func (*GitHubProvider) Name

func (g *GitHubProvider) Name() string

Name returns "github".

func (*GitHubProvider) UserInfo

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

UserInfo fetches the authenticated user's profile from GitHub's /user API and their verified primary email from /user/emails.

type GoogleProvider

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

GoogleProvider implements the Provider interface for Google OAuth2/OIDC. It uses PKCE S256 code challenge and requests offline access for refresh tokens.

func NewGoogleProvider

func NewGoogleProvider(clientID, clientSecret, redirectURI string) *GoogleProvider

NewGoogleProvider creates a Google OAuth2/OIDC provider with the given credentials and redirect URI.

func (*GoogleProvider) AuthURL

func (g *GoogleProvider) AuthURL(state, nonce, codeChallenge string) string

AuthURL returns the Google OAuth2 authorization URL with PKCE S256 code challenge, nonce for OIDC, and offline access type for refresh tokens.

func (*GoogleProvider) Exchange

func (g *GoogleProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)

Exchange trades an authorization code for tokens via Google's token endpoint, using the PKCE code verifier for validation.

func (*GoogleProvider) Name

func (g *GoogleProvider) Name() string

Name returns "google".

func (*GoogleProvider) UserInfo

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

UserInfo fetches the authenticated user's profile from Google's userinfo endpoint.

type OIDCProvider added in v0.8.0

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

OIDCProvider implements Provider for any standards-compliant OpenID Connect issuer (Okta, Auth0, Authentik, Keycloak, Entra, Google-OIDC, …). Endpoints are resolved via OIDC discovery ({issuer}/.well-known/openid-configuration), cached after the first fetch. Uses PKCE S256 + a nonce on the authorize request.

func NewOIDCProvider added in v0.8.0

func NewOIDCProvider(name, issuer, clientID, clientSecret, redirectURI, scopes string) *OIDCProvider

NewOIDCProvider builds a generic OIDC provider. name is the provider key used in routes/state (e.g. "okta"); scopes is optional (space-delimited).

func (*OIDCProvider) AuthURL added in v0.8.0

func (p *OIDCProvider) AuthURL(state, nonce, codeChallenge string) string

AuthURL builds the authorize URL. Returns "" if discovery fails (the handler's redirect guard rejects an empty/invalid URL).

func (*OIDCProvider) Exchange added in v0.8.0

func (p *OIDCProvider) Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)

Exchange swaps an authorization code for tokens at the discovered token endpoint.

func (*OIDCProvider) Name added in v0.8.0

func (p *OIDCProvider) Name() string

Name returns the provider key.

func (*OIDCProvider) SetGuard added in v1.0.3

func (p *OIDCProvider) SetGuard(g *outbound.Policy)

SetGuard installs the deployment's outbound destination policy on this provider: the operator's additions to the set of hosts its discovery document may name, and the dial-time check on the addresses those hosts resolve to.

It replaces the provider's client, because the dial-time half is a property of the transport and cannot be applied any other way. The end-to-end timeout is unchanged.

func (*OIDCProvider) UserInfo added in v0.8.0

func (p *OIDCProvider) UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)

UserInfo fetches the normalized profile from the discovered userinfo endpoint.

func (*OIDCProvider) VerifyIDToken added in v0.8.0

func (p *OIDCProvider) VerifyIDToken(ctx context.Context, idToken, expectedNonce string) (*UserInfo, error)

VerifyIDToken validates an OIDC ID token's signature (against the issuer's JWKS) and its iss, aud, exp and nonce claims, returning the normalized profile. It rejects unsigned/HMAC tokens and embedded-key headers (jku/x5u/x5c/jwk).

expectedNonce is the nonce minted for this login attempt and is mandatory. An empty value is rejected rather than read as "skip the nonce check": the nonce is the only claim binding the token to this browser's authorization request, so skipping it would reopen the ID-token / code-injection attack that RFC 9700 §4.5.3 requires the nonce to close. The obligation is discharged by the authorization-code flow in internal/handler/oauth.go, which mints the nonce at /authorize and round-trips it through the HMAC-signed state parameter.

Every failure path returns a nil profile: there is no partial result a caller could mistake for a verified identity.

type Provider

type Provider interface {
	// Name returns the provider key used in routes, the signed state parameter
	// and the social-account rows, for example "google" or "github".
	Name() string

	// AuthURL builds the provider's authorization endpoint URL. state is the
	// HMAC-signed CSRF/session binding, codeChallenge is the PKCE S256
	// challenge, and nonce binds the resulting OIDC ID token to this login
	// attempt. Non-OIDC providers ignore nonce, but callers must still pass a
	// unique value: [OIDCProvider.VerifyIDToken] rejects a login whose nonce is
	// empty. An implementation returns "" when it cannot build a URL, which the
	// handler's redirect guard treats as a failure.
	AuthURL(state, nonce, codeChallenge string) string

	// Exchange swaps an authorization code for tokens, presenting codeVerifier
	// as the PKCE proof. It never returns a partially populated TokenResponse:
	// a non-nil result means the provider accepted the code.
	Exchange(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)

	// UserInfo retrieves the profile behind accessToken and normalizes it to
	// [UserInfo]. For OIDC issuers this is the fallback path; a verified ID
	// token is preferred because it is signed and nonce-bound, while a userinfo
	// response is only as trustworthy as the transport.
	UserInfo(ctx context.Context, accessToken string) (*UserInfo, error)
}

Provider defines the interface for OAuth2/OIDC providers. Implementations must handle authorization URL construction, authorization code exchange, and user profile retrieval from the provider's API.

type TokenResponse

type TokenResponse struct {
	// AccessToken is the provider-issued access token (RFC 6749).
	AccessToken string // #nosec G117 -- OAuth2 response field per RFC 6749
	// RefreshToken is the provider-issued refresh token, if granted (RFC 6749).
	RefreshToken string // #nosec G117 -- OAuth2 response field per RFC 6749
	// IDToken is the OIDC ID token, present only for OIDC providers (e.g., Google).
	IDToken string
	// TokenType is the token type, typically "Bearer".
	TokenType string
	// ExpiresIn is the access token lifetime in seconds.
	ExpiresIn int
}

TokenResponse holds the OAuth2 token exchange response from a provider.

type UserInfo

type UserInfo struct {
	// ID is the user's unique identifier at the provider.
	ID string
	// Email is the user's primary email address.
	Email string
	// EmailVerified indicates whether the provider has confirmed the email address.
	EmailVerified bool
	// Name is the user's display name.
	Name string
	// AvatarURL is a URL to the user's profile picture.
	AvatarURL string
	// Provider is the name of the OAuth2 provider (e.g., "google", "github").
	Provider string
	// AuthTime is the instant the provider states it authenticated the user,
	// from the OIDC auth_time claim. It is the zero time whenever the provider
	// stated none: the claim is OPTIONAL in OIDC Core §2 unless the request sent
	// max_age or asked for auth_time as an essential claim, and no non-OIDC
	// provider has an equivalent, so most logins leave it zero.
	//
	// A caller must read the zero value as "not stated" and substitute an
	// instant it can vouch for. Passing it on as a timestamp dates the session
	// to the Unix epoch, which is the reading internal/service/token.go already
	// refuses to emit.
	AuthTime time.Time
}

UserInfo holds normalized user profile information retrieved from a provider. Fields are populated to a common schema regardless of the upstream provider.

Jump to

Keyboard shortcuts

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