oauth

package
v0.0.14 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package oauth signs them in with any OAuth 2 provider: GitHub, Microsoft, Slack, your own. The provider's page opens in the system's secure browser sheet, and PKCE stands in for a client secret, so none ships in the app. For Apple and Google, signin uses the phone's own sheets.

nimbus native plugin add oauth -scheme com.example.cafe

t, err := oauth.SignIn(ctx, oauth.Config{
	Endpoint:    oauth.Microsoft("common"),
	ClientID:    "your-app-id",
	RedirectURL: "com.example.cafe://auth",
	Scopes:      []string{"openid", "profile", "offline_access", "User.Read"},
})

On the web the page opens in a popup and comes back to the site's /_nn/oauth, such as https://cafe.example/_nn/oauth: register that address at the provider too.

Some providers, GitHub among them, still want a secret for the exchange. For those, Authorize gets the code on the phone and your server calls Exchange with the secret.

Index

Constants

This section is empty.

Variables

View Source
var GitHub = Endpoint{
	AuthURL:  "https://github.com/login/oauth/authorize",
	TokenURL: "https://github.com/login/oauth/access_token",
}

GitHub's endpoints. Its OAuth apps want the client secret for the exchange, so use Authorize on the phone and Exchange on your server.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Endpoint is the provider's: GitHub, Microsoft(tenant), or one you fill.
	Endpoint Endpoint
	// ClientID is your app's ID at the provider.
	ClientID string
	// RedirectURL is where the provider sends them back, such as
	// "com.example.cafe://auth". Its scheme is the one you gave plugin add,
	// and it must be registered at the provider exactly as written. On the
	// web it is the site's /_nn/oauth instead, whatever this says.
	RedirectURL string
	// Scopes are what you ask for.
	Scopes []string
	// Params go on the sign-in page's address as they are, such as
	// {"prompt": "select_account"}.
	Params map[string]string
	// Ephemeral keeps the browser's cookies out of it, so they sign in
	// afresh and iOS doesn't first ask to use the provider's site. iOS only.
	Ephemeral bool
	// ClientSecret is for your server's Exchange and Refresh only. Never
	// put it in the app: anyone can read what's in there.
	ClientSecret string
}

Config says which provider, and who's asking.

type Endpoint

type Endpoint struct {
	AuthURL  string // the page that asks them
	TokenURL string // where a code becomes a token
}

Endpoint is where a provider signs people in.

func Microsoft

func Microsoft(tenant string) Endpoint

Microsoft is Microsoft's identity platform. tenant is "common" for any account, "organizations" or "consumers", or your directory's ID.

type Error

type Error struct {
	Code        string // OAuth's error code
	Description string // the provider's words, when it gave any
}

Error is the provider saying no. Code is OAuth's: "access_denied" when they turned it down, "invalid_grant" for a used or expired code, and others.

func (*Error) Error

func (e *Error) Error() string

type Grant

type Grant struct {
	Code        string `json:"code"`        // the provider's one-time code
	Verifier    string `json:"verifier"`    // the PKCE secret only this sign-in knew
	RedirectURL string `json:"redirectURL"` // which the exchange must repeat
}

Grant is what the provider sent back: a one-time code, and the verifier that proves this app asked for it. Exchange turns it into a Token.

func Authorize

func Authorize(ctx context.Context, c Config) (Grant, error)

Authorize shows the provider's page and returns the code it sent back, without exchanging it. Send the Grant to your server when the exchange needs a secret.

type Token

type Token struct {
	AccessToken  string    `json:"access_token"`            // for the provider's API
	TokenType    string    `json:"token_type"`              // usually "Bearer"
	RefreshToken string    `json:"refresh_token,omitempty"` // for Refresh; only if the provider gives one
	IDToken      string    `json:"id_token,omitempty"`      // with the "openid" scope, from providers that do OpenID
	Scope        string    `json:"scope,omitempty"`         // what was granted, which can be less than asked
	Expiry       time.Time `json:"expiry"`                  // zero when the provider didn't say
}

Token is what the provider hands out.

func Exchange

func Exchange(ctx context.Context, c Config, g Grant) (Token, error)

Exchange turns a Grant into a Token. On the phone it runs inside SignIn; on your server, set ClientSecret.

func Refresh

func Refresh(ctx context.Context, c Config, refreshToken string) (Token, error)

Refresh gets a new access token with a refresh token, without showing them anything. The answer may carry a new refresh token: keep that one.

func SignIn

func SignIn(ctx context.Context, c Config) (Token, error)

SignIn shows the provider's page and returns their token. Backing out gives a plugin error with code plugin.Cancelled.

Jump to

Keyboard shortcuts

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