oauth2

package module
v0.0.0-...-ed422c3 Latest Latest
Warning

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

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

README

go-ruby-oauth2/oauth2

oauth2 — go-ruby-oauth2

Docs License Go Coverage

A pure-Go (no cgo) reimplementation of the deterministic protocol pieces of Ruby's oauth2 gem — the interpreter-independent OAuth2 client core: building authorization URLs and per-grant token-request specifications, and parsing token/error responses into an AccessToken. It reproduces the gem's byte-level output (sorted, percent- encoded query strings; basic-auth vs request-body vs TLS client authentication; JSON and form-encoded response parsing) — without any Ruby runtime.

It is the OAuth2 client for go-embedded-ruby, but a standalone, reusable module — a sibling of go-ruby-regexp, go-ruby-erb and go-ruby-yaml.

What it is — and isn't. The URL/param construction and response parsing are fully deterministic and need no interpreter, so they live here as pure Go. The HTTP round-trip itself is a host seam: the library builds a Request and a host (wiring to go-ruby-net-http / faraday) turns it into a Response via a RoundTripper. This mirrors the gem, where Faraday performs the transport.

Features

Faithful port of the oauth2 gem's client protocol, validated against the gem on every platform where it is installed:

  • Authorization URLsAuthCode().AuthorizeURL(...) merges the client_id and response_type=code defaults and query-encodes every param (redirect_uri, scope, state, PKCE, provider extras) with keys sorted and the RFC 3986 unreserved set left literal (space → %20), byte-faithful to the gem.
  • Every grant — authorization code, client credentials, resource-owner password, JWT-bearer assertion, and refresh token; each builds the token request spec (form body / query params) the gem hands to Faraday.
  • Client authentication schemesbasic_auth (the default; Authorization: Basic base64(id:secret)), request_body (client_id + client_secret in the body), and tls_client_auth (client_id only, RFC 8705).
  • Token methodPOST (form body) or GET (query params).
  • Response parsing — content-type dispatch (application/json, any +json, text/json, application/x-www-form-urlencoded) into an AccessToken with token, refresh_token, expires_at/expires?/expired?, token_type, scope, and residual provider params (in response order).
  • AccessToken — expiry derivation (expires_inexpires_at), the refresh request builder (preserving the old refresh token when the response omits one), to_hash, and resource-request injection in header / query / body mode (Bearer/MAC/custom header_format).
  • Error — extracts error / error_description from an error response and composes the gem's message.
  • PKCEcode_challenge for the S256 and plain methods (RFC 7636).

CGO-free, dependency-free, 100% test coverage, gofmt + go vet clean, and green across the six 64-bit Go targets (amd64, arm64, riscv64, loong64, ppc64le, s390x).

Install

go get github.com/go-ruby-oauth2/oauth2

Usage

package main

import (
	"fmt"

	"github.com/go-ruby-oauth2/oauth2"
)

func main() {
	client := oauth2.NewClient("myid", "mysecret", oauth2.Options{
		Site:         "https://provider.example.com",
		AuthorizeURL: "/oauth/authorize",
		TokenURL:     "/oauth/token",
	})

	// 1. Authorization URL to redirect the user-agent to.
	url := client.AuthCode().AuthorizeURL(oauth2.Params{
		{"redirect_uri", "https://app/cb"},
		{"scope", "read write"},
		{"state", "xyz"},
	})
	fmt.Println(url)
	// https://provider.example.com/oauth/authorize?client_id=myid&
	//   redirect_uri=https%3A%2F%2Fapp%2Fcb&response_type=code&
	//   scope=read%20write&state=xyz

	// 2. Build the token request for the returned code; run it through the host
	//    transport (the seam), then parse the response into an AccessToken.
	req := client.AuthCode().GetTokenRequest("thecode", oauth2.Params{
		{"redirect_uri", "https://app/cb"},
	})
	// req.Method == "POST", req.URL, req.EncodedBody(),
	// req.Headers has Authorization: Basic base64(id:secret)

	resp, _ := transport.RoundTrip(req) // host seam (go-ruby-net-http / faraday)
	tok, _ := client.ParseToken(resp)
	fmt.Println(tok.Token, tok.ExpiresAt, tok.Expired())

	// 3. Inject the token into a resource request.
	headers, _, _ := tok.ApplyTo(nil, nil, nil) // Authorization: Bearer <token>
	_ = headers
}

The transport is any oauth2.RoundTripper:

type RoundTripper interface {
	RoundTrip(req *oauth2.Request) (*oauth2.Response, error)
}

PKCE

verifier := "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
challenge := oauth2.CodeChallenge(verifier, oauth2.PKCES256)

url := client.AuthCode().AuthorizeURL(oauth2.Params{
	{"redirect_uri", "https://app/cb"},
	{"code_challenge", challenge},
	{"code_challenge_method", "S256"},
})
// exchange later with a code_verifier param in GetTokenRequest's extra params

Value model

Parameters and parsed bodies are carried as an ordered string→string Map; promoted token fields become AccessToken fields and the rest live in AccessToken.Params (in response order). A host (go-embedded-ruby / rbgo) maps its Ruby OAuth2::Client / AccessToken objects to and from these shapes.

gem this package
OAuth2::Client.new(id, secret, ...) NewClient(id, secret, Options{...})
client.auth_code.authorize_url(...) client.AuthCode().AuthorizeURL(params)
client.<grant>.get_token(...) client.<Grant>().GetTokenRequest(...) + client.ParseToken(resp)
OAuth2::AccessToken *AccessToken
OAuth2::Response#parsed (*Response).Parsed()
OAuth2::Error *Error
Faraday transport RoundTripper (host seam)

API

func NewClient(id, secret string, opts Options) *Client
func (c *Client) AuthorizeURL() string
func (c *Client) TokenURL() string
func (c *Client) ParseToken(resp *Response) (*AccessToken, error)
func (c *Client) ParseRefreshToken(resp *Response, prevRefresh string) (*AccessToken, error)

func (c *Client) AuthCode() AuthCode
func (c *Client) ClientCredentials() ClientCredentials
func (c *Client) Password() Password
func (c *Client) Assertion() Assertion
func (c *Client) Refresh() Refresh

func (s AuthCode) AuthorizeURL(params Params) string
func (s AuthCode) GetTokenRequest(code string, extra Params) *Request
// ... one GetTokenRequest per grant strategy

type AccessToken struct { Token, RefreshToken string; ExpiresAt int64; Params *Map; Mode; HeaderFormat, ParamName string }
func (t *AccessToken) Expires() bool
func (t *AccessToken) Expired() bool
func (t *AccessToken) RefreshRequest(extra ...Param) (*Request, error)
func (t *AccessToken) ApplyTo(headers, params, body *Map) (h, p, b *Map)
func (t *AccessToken) ToHash() *Map

type Request struct { Method, URL string; Params, Body, Headers *Map }
func (r *Request) EncodedBody() string
func (r *Request) FullURL() string

type Response struct { Status int; Headers *Map; Body string }
func (r *Response) Parsed() map[string]any
func (r *Response) ContentType() string

type Error struct { Response *Response; Code, Description string }
func (e *Error) Error() string
func (e *Error) FirstLine() string

func CodeChallenge(verifier string, method PKCEMethod) string // PKCE S256 / plain

type RoundTripper interface { RoundTrip(*Request) (*Response, error) }

Tests & coverage

The suite pairs deterministic, ruby-free tests (which alone hold coverage at 100%, so the qemu cross-arch and Windows lanes pass the gate) with a differential oracle against the reference oauth2 gem: authorize URLs, token-request specs (each grant × auth-scheme × method), PKCE challenges, and parsed token/error responses are diffed byte-for-byte against the gem. The oracle scripts $stdout.binmode and skip themselves where the gem is absent.

COVERPKG=$(go list ./... | paste -sd, -)
go test -race -coverpkg="$COVERPKG" -coverprofile=cover.out ./...
go tool cover -func=cover.out | tail -1   # 100.0%

License

BSD-3-Clause — see LICENSE. Copyright the go-ruby-oauth2/oauth2 authors.

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

Documentation

Overview

Package oauth2 is a pure-Go (CGO-free) reimplementation of the deterministic protocol pieces of Ruby's `oauth2` gem (the OAuth2 client): building authorization URLs and token-request specifications, and parsing token and error responses. It is the interpreter-independent core the gem shares across grant strategies, without any Ruby runtime.

What it is — and isn't

The URL/param construction (authorize-URL query encoding, per-grant token request bodies, basic-auth vs request-body client authentication, PKCE) and response parsing (JSON / form-encoded token bodies, error extraction) are fully deterministic and need no interpreter, so they live here as pure Go. The HTTP round-trip itself is a host seam: the library builds a Request and a host (wiring to go-ruby-net-http / faraday) turns it into a Response via a RoundTripper. This mirrors the gem, where Faraday performs the transport.

Flow

client := oauth2.NewClient("id", "secret", oauth2.Options{
	Site:         "https://provider.example.com",
	AuthorizeURL: "/oauth/authorize",
	TokenURL:     "/oauth/token",
})

// 1. Build the authorization URL to redirect the user to.
url := client.AuthCode().AuthorizeURL(oauth2.Params{
	{"redirect_uri", "https://app/cb"}, {"scope", "read"}, {"state", "xyz"},
})

// 2. Build the token request for the returned code, run it through the host
//    transport, and parse the response into an AccessToken.
req := client.AuthCode().GetTokenRequest("thecode", oauth2.Params{
	{"redirect_uri", "https://app/cb"},
})
resp, _ := transport.RoundTrip(req)   // host seam
tok, _ := client.ParseToken(resp)

Value model

Parameters and parsed bodies are carried as an ordered string→string Map; residual token fields live in AccessToken.Params. A host (go-embedded-ruby / rbgo) maps its Ruby Hash/AccessToken objects to and from these shapes.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CodeChallenge

func CodeChallenge(verifier string, method PKCEMethod) string

CodeChallenge derives the PKCE code_challenge for a code_verifier under the given method (RFC 7636 §4.2). For PKCES256 it returns the base64url (no padding) of SHA-256(verifier); for PKCEPlain it returns the verifier unchanged. An unknown method is treated as plain.

The verifier and challenge are added to the authorize URL and token request as the code_challenge / code_challenge_method / code_verifier params by the caller; this helper only performs the deterministic transformation.

Types

type AccessToken

type AccessToken struct {

	// Token is the bearer/opaque access-token string.
	Token string
	// RefreshToken is the refresh token, or "" if none was issued.
	RefreshToken string
	// ExpiresAt is the absolute expiry as a Unix timestamp, or 0 when the token
	// does not expire (Expires reports whether it is set).
	ExpiresAt int64
	// Params holds the residual response members not promoted to a named field
	// (token_type, scope, and any provider extras), in response order.
	Params *Map

	// Mode / HeaderFormat / ParamName control resource-request injection.
	Mode         Mode
	HeaderFormat string
	ParamName    string
	// contains filtered or unexported fields
}

AccessToken is a parsed OAuth2 access token, mirroring OAuth2::AccessToken. It binds the token to its issuing Client so [AccessToken.Refresh] can build the refresh request. The value model rbgo maps: Token/RefreshToken/ExpiresAt/ TokenType plus the residual Params.

func AccessTokenFromHash

func AccessTokenFromHash(client *Client, h map[string]any, order []string) *AccessToken

AccessTokenFromHash builds an AccessToken from a parsed token-response map, mirroring OAuth2::AccessToken.from_hash. It promotes access_token, refresh_token, token_type, expires_at, expires_in, mode, header_format and param_name; every other member is retained in Params (in the given order). When expires_in is present and expires_at is not, ExpiresAt is derived as now + expires_in (the gem's behaviour).

order lists the response keys in their original order so Params preserves it; pass nil to fall back to unspecified iteration for the residuals.

func NewAccessToken

func NewAccessToken(client *Client, token string) *AccessToken

NewAccessToken builds a token bound to client with default injection options (header mode, "Bearer %s", "access_token"), like OAuth2::AccessToken.new.

func (*AccessToken) ApplyTo

func (t *AccessToken) ApplyTo(headers, params, body *Map) (h, p, b *Map)

ApplyTo injects the token into a resource request per the token's Mode. It mutates and returns the given headers, params and body maps (any may be nil and will be created on demand for its mode). This mirrors OAuth2::AccessToken#headers / the request-mode handling.

  • ModeHeader: sets Authorization to HeaderFormat with the token substituted.
  • ModeQuery: sets params[ParamName] = token.
  • ModeBody: sets body[ParamName] = token.

func (*AccessToken) AuthorizationHeader

func (t *AccessToken) AuthorizationHeader() string

AuthorizationHeader returns the Authorization header value for the header mode (HeaderFormat with the token substituted), a convenience over AccessToken.ApplyTo.

func (*AccessToken) Expired

func (t *AccessToken) Expired() bool

Expired reports whether the token has expired: it must have an expiry and that expiry must be at or before now (OAuth2::AccessToken#expired?).

func (*AccessToken) Expires

func (t *AccessToken) Expires() bool

Expires reports whether the token carries an expiry (OAuth2::AccessToken#expires?).

func (*AccessToken) Get

func (t *AccessToken) Get(key string) (string, bool)

Get returns a residual param by name (OAuth2::AccessToken#[]).

func (*AccessToken) RefreshRequest

func (t *AccessToken) RefreshRequest(extra ...Param) (*Request, error)

RefreshRequest builds the token-endpoint Request that exchanges this token's refresh token for a new access token, mirroring OAuth2::AccessToken#refresh's request. extra merges additional body params. It returns an error when the token has no refresh token (as the gem raises).

func (*AccessToken) Scope

func (t *AccessToken) Scope() string

Scope returns the scope residual param, or "".

func (*AccessToken) ToHash

func (t *AccessToken) ToHash() *Map

ToHash renders the token as an ordered map matching OAuth2::AccessToken#to_hash: the residual params first (in order), then access_token, refresh_token, expires_at, mode, header_format, param_name. refresh_token and expires_at are omitted when unset.

func (*AccessToken) TokenType

func (t *AccessToken) TokenType() string

TokenType returns the token_type residual param (e.g. "bearer"), or "".

type Assertion

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

Assertion is the assertion (JWT-bearer) grant strategy (OAuth2::Strategy::Assertion). The signed assertion is supplied by the caller (or a host binding to go-ruby-jwt) as the `assertion` param.

func (Assertion) GetTokenRequest

func (s Assertion) GetTokenRequest(grantType, assertion string, extra Params) *Request

GetTokenRequest builds the assertion-grant token request. grantType is the grant_type URI (e.g. "urn:ietf:params:oauth:grant-type:jwt-bearer"); assertion is the signed JWT bearer assertion; extra carries any additional params.

type AuthCode

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

AuthCode is the authorization-code grant strategy (OAuth2::Strategy::AuthCode).

func (AuthCode) AuthorizeURL

func (s AuthCode) AuthorizeURL(params Params) string

AuthorizeURL builds the authorization URL to redirect the user-agent to, mirroring OAuth2::Strategy::AuthCode#authorize_url. The client_id and response_type=code defaults are merged in unless params overrides them; every param (redirect_uri, scope, state, PKCE code_challenge, provider extras) is query-encoded with keys sorted, byte-faithful to the gem.

func (AuthCode) GetTokenRequest

func (s AuthCode) GetTokenRequest(code string, extra Params) *Request

GetTokenRequest builds the token request that exchanges an authorization code for a token, mirroring OAuth2::Strategy::AuthCode#get_token. The body carries grant_type=authorization_code and the code, plus any extra params (typically redirect_uri and a PKCE code_verifier); client authentication is applied per the client's auth scheme.

type AuthScheme

type AuthScheme string

AuthScheme selects how client credentials authenticate the token request, mirroring OAuth2::Client's :auth_scheme.

const (
	// AuthBasic sends the credentials as an HTTP Basic Authorization header
	// (base64("id:secret")); the default.
	AuthBasic AuthScheme = "basic_auth"
	// AuthRequestBody sends client_id and client_secret as form-body params.
	AuthRequestBody AuthScheme = "request_body"
	// AuthTLSClientAuth sends only client_id in the body (the secret is carried
	// by the mutual-TLS certificate, out of band), per RFC 8705.
	AuthTLSClientAuth AuthScheme = "tls_client_auth"
)

type Client

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

Client is an OAuth2 client bound to a set of credentials and endpoints, mirroring OAuth2::Client. It builds authorization URLs and token requests and parses responses; the HTTP transport is a host seam (see RoundTripper).

func NewClient

func NewClient(id, secret string, opts Options) *Client

NewClient returns a Client for the given client id and secret. opts fills in the site and endpoints; unset endpoint paths default to the gem's "oauth/authorize" and "oauth/token".

func (*Client) Assertion

func (c *Client) Assertion() Assertion

Assertion returns the assertion strategy for this client.

func (*Client) AuthCode

func (c *Client) AuthCode() AuthCode

AuthCode returns the authorization-code strategy for this client.

func (*Client) AuthorizeURL

func (c *Client) AuthorizeURL() string

AuthorizeURL returns the fully-qualified authorization endpoint (AuthorizeURL resolved against Site), matching OAuth2::Client#authorize_url with no params.

func (*Client) ClientCredentials

func (c *Client) ClientCredentials() ClientCredentials

ClientCredentials returns the client-credentials strategy for this client.

func (*Client) ID

func (c *Client) ID() string

ID returns the client identifier.

func (*Client) ParseRefreshToken

func (c *Client) ParseRefreshToken(resp *Response, prevRefresh string) (*AccessToken, error)

ParseRefreshToken is like Client.ParseToken but preserves prevRefresh when the response omits a new refresh_token, matching OAuth2::AccessToken#refresh.

func (*Client) ParseToken

func (c *Client) ParseToken(resp *Response) (*AccessToken, error)

ParseToken turns a token-endpoint Response into an AccessToken, mirroring OAuth2::Client#get_token's success path: a >= 400 status becomes an Error; otherwise the parsed body is promoted into an AccessToken bound to this client. prevRefresh, when non-empty, is retained as the refresh token if the response omits one (the gem's refresh behaviour, which keeps the old refresh token).

func (*Client) Password

func (c *Client) Password() Password

Password returns the password strategy for this client.

func (*Client) Refresh

func (c *Client) Refresh() Refresh

Refresh returns the refresh strategy for this client.

func (*Client) TokenURL

func (c *Client) TokenURL() string

TokenURL returns the fully-qualified token endpoint, matching OAuth2::Client#token_url.

type ClientCredentials

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

ClientCredentials is the client-credentials grant strategy (OAuth2::Strategy::ClientCredentials).

func (ClientCredentials) GetTokenRequest

func (s ClientCredentials) GetTokenRequest(extra Params) *Request

GetTokenRequest builds the client-credentials token request (grant_type=client_credentials plus any extra params such as scope).

type Error

type Error struct {
	Response    *Response
	Code        string
	Description string
	// contains filtered or unexported fields
}

Error is raised for an unsuccessful token response, mirroring OAuth2::Error. It carries the originating Response and the extracted OAuth error fields. Code is the `error` member of the parsed body (or "" if absent); Description is `error_description`. Message reproduces the gem's assembled message.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) FirstLine

func (e *Error) FirstLine() string

FirstLine returns the first line of the error message (the "code: description" summary), a convenience for logging without the appended raw body.

type Map

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

Map is an insertion-ordered string→string map used for request parameters and parsed form bodies. Ruby's `oauth2` gem threads plain Hashes through the flow; this ordered map mirrors that while giving deterministic iteration for the (unsorted) request-body specs and stable, sorted output for URLs.

func NewMap

func NewMap() *Map

NewMap returns an empty ordered Map.

func (*Map) Get

func (m *Map) Get(key string) (string, bool)

Get returns the value for key and whether it was present.

func (*Map) Has

func (m *Map) Has(key string) bool

Has reports whether key is present.

func (*Map) Len

func (m *Map) Len() int

Len reports the number of entries.

func (*Map) Pairs

func (m *Map) Pairs() []Pair

Pairs returns the entries in insertion order. The slice must not be mutated.

func (*Map) Set

func (m *Map) Set(key, val string)

Set inserts or replaces the entry for key, preserving the position of an existing key when it is overwritten (last write wins on value, first write wins on order — the gem's Hash semantics).

func (*Map) SetDefault

func (m *Map) SetDefault(key, val string)

SetDefault inserts key→val only if key is absent, mirroring the gem's habit of filling in a default (client_id, grant_type, response_type) without clobbering a caller-supplied override.

type Mode

type Mode string

Mode selects how AccessToken.ApplyTo carries the token to a resource request, mirroring OAuth2::AccessToken's :mode.

const (
	// ModeHeader carries the token in the Authorization header (the default).
	ModeHeader Mode = "header"
	// ModeQuery carries the token as a query parameter named by ParamName.
	ModeQuery Mode = "query"
	// ModeBody carries the token as a form-body parameter named by ParamName.
	ModeBody Mode = "body"
)

type Options

type Options struct {
	// Site is the base URL against which relative AuthorizeURL/TokenURL resolve.
	Site string
	// AuthorizeURL is the authorization endpoint: an absolute URL, or a path
	// resolved against Site. Defaults to "oauth/authorize".
	AuthorizeURL string
	// TokenURL is the token endpoint: an absolute URL, or a path resolved against
	// Site. Defaults to "oauth/token".
	TokenURL string
	// AuthScheme selects client authentication (default AuthBasic).
	AuthScheme AuthScheme
	// TokenMethod is the token-request HTTP method (default TokenPost).
	TokenMethod TokenMethod
}

Options configures a Client, mirroring the OAuth2::Client keyword options that affect URL/request construction. Empty fields take the gem's defaults.

type PKCEMethod

type PKCEMethod string

PKCEMethod is a PKCE code-challenge transformation (RFC 7636).

const (
	// PKCES256 is the SHA-256 transformation: challenge = BASE64URL(SHA256(verifier)).
	PKCES256 PKCEMethod = "S256"
	// PKCEPlain is the identity transformation: challenge = verifier.
	PKCEPlain PKCEMethod = "plain"
)

type Pair

type Pair struct {
	Key string
	Val string
}

Pair is one entry of an ordered string-keyed map.

type Param

type Param struct {
	Key string
	Val string
}

Param is one ordered key/value request parameter; a []Param (Params) lets callers supply parameters with a deterministic order (the gem accepts a Ruby Hash — here order is explicit for reproducibility).

type Params

type Params = []Param

Params is an ordered list of request parameters.

type Password

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

Password is the resource-owner password-credentials grant strategy (OAuth2::Strategy::Password).

func (Password) GetTokenRequest

func (s Password) GetTokenRequest(username, password string, extra Params) *Request

GetTokenRequest builds the password-grant token request (grant_type=password with username and password, plus any extra params).

type Refresh

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

Refresh is the refresh-token grant strategy. It builds the request that exchanges a refresh token for a new access token (the request half of OAuth2::AccessToken#refresh, usable independently of an AccessToken).

func (Refresh) GetTokenRequest

func (s Refresh) GetTokenRequest(refreshToken string, extra Params) *Request

GetTokenRequest builds the refresh-token request (grant_type=refresh_token with the given refresh token, plus extra params).

type Request

type Request struct {
	Method  string
	URL     string
	Params  *Map
	Body    *Map
	Headers *Map
}

Request is the deterministic specification of a single HTTP round-trip the library builds for a token operation. The HTTP transport itself is a host seam: a host (wiring to go-ruby-net-http / faraday) turns a Request into a Response via a RoundTripper. All fields are byte-faithful to what the `oauth2` gem hands to Faraday.

  • Method is "POST" or "GET" (from the client's token_method).
  • URL is the fully-qualified token endpoint.
  • Params carries the form fields when Method is GET (they go in the query string); it is empty for POST.
  • Body carries the form fields when Method is POST (encoded application/x-www-form-urlencoded); it is empty for GET.
  • Headers carries the request headers (Content-Type, and Authorization for the basic-auth scheme).

func (*Request) EncodedBody

func (r *Request) EncodedBody() string

EncodedBody returns the request body form-encoded (sorted keys, %-escaped), suitable for an application/x-www-form-urlencoded POST. It is empty for a GET request.

func (*Request) FullURL

func (r *Request) FullURL() string

FullURL returns URL with the GET params appended as a query string, or URL unchanged for a POST request.

type Response

type Response struct {
	Status  int
	Headers *Map
	Body    string
	// contains filtered or unexported fields
}

Response is the raw HTTP response from the token endpoint, as returned by a RoundTripper. It mirrors OAuth2::Response: Status, Headers and the raw Body, with Response.Parsed lazily decoding the body by content type.

func NewResponse

func NewResponse(status int, headers *Map, body string) *Response

NewResponse builds a Response from its parts.

func (*Response) ContentType

func (r *Response) ContentType() string

ContentType returns the response's Content-Type header value with any parameters (e.g. "; charset=utf-8") stripped and lower-cased, matching OAuth2::Response#content_type's effective media type.

func (*Response) Parsed

func (r *Response) Parsed() map[string]any

Parsed decodes the body into a map keyed by string, dispatching on the content type exactly as OAuth2::Response does: a JSON media type (application/json, or any "+json") is JSON-decoded; a form media type (application/x-www-form-urlencoded) is form-decoded; anything else (or an undecodable body) yields an empty map. The result is memoised.

type RoundTripFunc

type RoundTripFunc func(req *Request) (*Response, error)

RoundTripFunc adapts a function to the RoundTripper interface.

func (RoundTripFunc) RoundTrip

func (f RoundTripFunc) RoundTrip(req *Request) (*Response, error)

RoundTrip calls f(req).

type RoundTripper

type RoundTripper interface {
	RoundTrip(req *Request) (*Response, error)
}

RoundTripper is the host transport seam: it performs the HTTP round-trip for a built Request and returns the raw Response. Implementations live in the host (go-ruby-net-http / faraday); this package never opens a socket.

type TokenMethod

type TokenMethod string

TokenMethod is the HTTP method used for the token request.

const (
	// TokenPost issues the token request as a POST with a form body (default).
	TokenPost TokenMethod = "post"
	// TokenGet issues the token request as a GET with query params.
	TokenGet TokenMethod = "get"
)

Jump to

Keyboard shortcuts

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