Skip to content

x/oauth2: Device authorization grant #58126

@hickford

Description

@hickford

issue golang/oauth2#418

Objective: support OAuth 2.0 Device Authorization Grant, RFC 8628 (Proposed Standard since 2019)

Add DeviceAuthURL field to type Endpoint

type Endpoint struct {
	AuthURL       string
+	DeviceAuthURL string
	TokenURL      string

Define a function to make the Device Authorization response and define a new struct to hold the response.

// DeviceAuth makes the RFC 8628 Device Authorization request and
// returns the response or an error. 
// https://www.rfc-editor.org/rfc/rfc8628#section-3.1
func (c *Config) DeviceAuth(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error)

// DeviceAuthResponse holds the RFC 8628 Device Authorization Response.
// https://www.rfc-editor.org/rfc/rfc8628#section-3.2
type DeviceAuthResponse struct {
	DeviceCode              string `json:"device_code"`
	UserCode                string `json:"user_code"`
	VerificationURI         string `json:"verification_uri"`
	VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
	// Expiry is derived from the expires_in parameter in the response.
        Expiry               time.Time    `json:"expires_in,omitempty"`
	Interval                int    `json:"interval,omitempty"`
}

func (r *DeviceAuthResponse) UnmarshalJSON([]byte) error

func (r DeviceAuthResponse) MarshalJSON() ([]byte, error)

Note that Expiry is a time.Time even though the RFC 8628 json parameter expires_in is an int counting seconds. This convenience follows the design of oauth2.Token.Expiry. Custom JSON marshalling is necessary.

// Poll makes the device access token request until it receives a
// token response or a fatal error.
// https://www.rfc-editor.org/rfc/rfc8628#section-3.4
func (c *Config) DeviceAccessToken(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error)

Here's a change including implementation golang/oauth2#609

Working example of an app using the proposed API to add support for headless devices in ~20 lines https://github.com/hickford/git-credential-oauth/pull/9/files#diff-2873f79a86c0d8b3335cd7731b0ecf7dd4301eb19a82ef7a1cba7589b5252261

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions