Help us shape the future of Go! Take the 2026 Go Developer Survey

deviceflow

package
v0.55.1 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package deviceflow implements the RFC 8628 OAuth 2.0 Device Authorization Grant's token-endpoint handler.

Index

Constants

This section is empty.

Variables

View Source
var ErrAuthorizationPending = &fosite.RFC6749Error{
	ErrorField:       "authorization_pending",
	DescriptionField: "The authorization request is still pending as the end user hasn't yet completed the user-interaction steps.",
	CodeField:        http.StatusBadRequest,
}

ErrAuthorizationPending indicates the device flow is still awaiting the end user's action at the verification URI (RFC 8628 Section 3.5).

View Source
var ErrExpiredToken = &fosite.RFC6749Error{
	ErrorField:       "expired_token",
	DescriptionField: "The device_code has expired. The client must restart the device authorization flow.",
	CodeField:        http.StatusBadRequest,
}

ErrExpiredToken indicates the device_code has expired and the client must restart the device authorization flow (RFC 8628 Section 3.5).

This is deliberately its own sentinel rather than a reuse of fosite's fosite.ErrTokenExpired: that error's wire "error" field is "invalid_token" (RFC 6750 Section 3.1's bearer-token-error vocabulary), not RFC 8628 Section 3.5's "expired_token". Reusing it would emit the wrong error code to device-flow clients.

View Source
var ErrSlowDown = &fosite.RFC6749Error{
	ErrorField:       "slow_down",
	DescriptionField: "The client polled the token endpoint faster than the interval permitted.",
	CodeField:        http.StatusBadRequest,
}

ErrSlowDown indicates the client polled faster than the granted interval (RFC 8628 Section 3.5).

Functions

func Factory

func Factory(deviceStorage authstorage.DeviceCodeStorage, minInterval time.Duration) server.Factory

Factory returns a server.Factory that registers the RFC 8628 device-code grant, mirroring how the tokenexchange and jwtbearer factories are constructed in server_impl.go's buildProvider.

Types

type Handler

type Handler struct {
	DeviceStorage authstorage.DeviceCodeStorage
	CoreStorage   oauth2.CoreStorage
	Strategy      oauth2.CoreStrategy
	Config        deviceFlowConfig
	// MinInterval is the minimum time a client must wait between polls
	// (RFC 8628 Section 3.5). A poll that arrives sooner is rejected with
	// slow_down.
	MinInterval time.Duration
}

Handler implements fosite's TokenEndpointHandler for RFC 8628's urn:ietf:params:oauth:grant-type:device_code grant.

A device_code is single-use: HandleTokenEndpointRequest deletes it from DeviceStorage as soon as it observes DeviceRequestStatusAuthorized, before PopulateTokenEndpointResponse ever issues a token, so a device_code can never be redeemed twice.

func (*Handler) CanHandleTokenEndpointRequest

func (*Handler) CanHandleTokenEndpointRequest(_ context.Context, requester fosite.AccessRequester) bool

CanHandleTokenEndpointRequest returns true if the request's grant_type is the RFC 8628 device_code grant type.

func (*Handler) CanSkipClientAuth

func (*Handler) CanSkipClientAuth(_ context.Context, _ fosite.AccessRequester) bool

CanSkipClientAuth always returns false: the device_code grant does not exempt the client from standard authentication. The client authenticates with whatever method it registered with, exactly as for every other grant; only grants that attach a synthetic, unregistered client (see storage.NewSyntheticClient) skip authentication, and this is not one of them.

func (*Handler) HandleTokenEndpointRequest

func (h *Handler) HandleTokenEndpointRequest(ctx context.Context, requester fosite.AccessRequester) error

HandleTokenEndpointRequest validates the device_code, enforces the RFC 8628 polling contract (slow_down, authorization_pending, access_denied, expired_token), and — once the device request has been authorized — attaches a session and consumes (deletes) the device_code so it cannot be redeemed twice.

func (*Handler) PopulateTokenEndpointResponse

func (h *Handler) PopulateTokenEndpointResponse(
	ctx context.Context, requester fosite.AccessRequester, responder fosite.AccessResponder,
) error

PopulateTokenEndpointResponse issues the access token and, when the client is registered for the refresh_token grant, a refresh token.

Jump to

Keyboard shortcuts

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