authorization_code

package
v0.1.8 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2025 License: MIT Imports: 12 Imported by: 1

README

Authorization Code Flow

The authorization_code package provides OAuth2 authorization code flow implementations for Go applications. This package is imported as github.com/kinde-oss/kinde-go/oauth2/authorization_code.

Overview

The authorization code flow is a backend authorization flow that requires a client secret. It is designed to be used as a server-side auth flow and does not expose tokens to the browser. User sessions need to be managed by other means, for example via session cookies.

Go Imports

import (
    "github.com/kinde-oss/kinde-go/oauth2/authorization_code" // required
    "github.com/kinde-oss/kinde-go/jwt" // optional - for JWT token validation
)

Standard Authorization Code Flow

Basic Usage
kindeAuthFlow, err := authorization_code.NewAuthorizationCodeFlow(
  "<issuer URL>",                                       // Kinde subdomain or any auth provider conforming to the spec
  "<client_id>", "<client_secret>", "<callback URL>",
  authorization_code.WithSessionHooks(<ISessionHooks implementation>),     // example of storage for gin framework is gin_kinde.UseKindeAuth(...)
  authorization_code.WithOffline(),                                        // adds offline scope and starts managing refresh tokens
  authorization_code.WithAudience("<your API audience>"),                  // requesting an API audience
  authorization_code.WithTokenValidation(
    true,                                               // will validate token signature via JWKS
    jwt.WillValidateAlgorithm(),                        // will validate the token alg is RS256
    jwt.WillValidateAudience("<your API audience>"),    // will confirm that received token includes correct audience
  ),
)
Available Methods
Method Description Parameters Returns
GetAuthURL Returns the URL to redirect the user to start the authentication pipeline. none string
ExchangeCode Exchanges the authorization code for a token and establishes KindeContext. ctx context.Context, authorizationCode string, receivedState string error
GetClient Returns an HTTP client for calling external services, automatically refreshing tokens if offline is requested. ctx context.Context (*http.Client, error)
IsAuthenticated Checks if the user is authenticated. ctx context.Context (bool, error)
Logout Clears local tokens and logs the user out. none error
AuthorizationCodeReceivedHandler Helper handler middleware for the code exchanger. w http.ResponseWriter, r *http.Request none

Device Authorization Flow

The device authorization flow is an extension of the authorization code flow that separates token requester and receiver. It is best used for devices and environments with limited input capabilities, such as CLIs, TVs, etc.

Basic Usage
deviceFlow, err := authorization_code.NewDeviceAuthorizationFlow(
  "<issuer_domain>",                                    // Kinde subdomain or any auth provider conforming to the spec
  authorization_code.WithClientID("<your-client-id>"),  // optional, when business provides a default device application, otherwise required
  authorization_code.WithClientSecret("<your-client-secret>"), // optional (used when device flow is used against backend application with a secret)
  authorization_code.WithSessionHooks(<ISessionHooks implementation>),      // used for storing/retrieving tokens
  authorization_code.WithOffline(),                     // optional - include if you'd like to maintain refresh tokens and a long session
  authorization_code.WithTokenValidation(
    true,                                               // will validate token signature via JWKS
    jwt.WillValidateAlgorithm(),                        // will validate the token alg is RS256
  ),
)
Available Methods
Method Description Parameters Returns
StartDeviceAuth Starts the device authorization flow and returns the device authorization response. ctx context.Context (*oauth2.DeviceAuthResponse, error)
ExchangeDeviceAccessToken Exchanges the device code for an access token. ctx context.Context, da *oauth2.DeviceAuthResponse, opts ...oauth2.AuthCodeOption error
GetClient Returns an HTTP client for calling external services, automatically refreshing tokens if offline is requested. ctx context.Context (*http.Client, error)
IsAuthenticated Checks if the user is authenticated. ctx context.Context (bool, error)
Logout Clears local tokens and logs the user out. none error
GetToken Returns the token for the current session. ctx context.Context (*jwt.Token, error)
InjectTokenMiddleware Middleware that injects the auth token into request context. next http.Handler http.Handler

Middleware

The authorization code flow package provides several middleware options to simplify integration with popular Go web frameworks and HTTP handlers.

Built-in HTTP Handler Middleware

The AuthorizationCodeReceivedHandler method provides a built-in HTTP handler for processing OAuth2 callbacks:

// Set up your callback route
http.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
    kindeAuthFlow.AuthorizationCodeReceivedHandler(w, r)
})

This handler automatically:

  • Extracts the authorization code and state from the request
  • Validates the state parameter
  • Exchanges the code for tokens
  • Stores the tokens using your session hooks
Gin Framework Middleware

For Gin applications, use the gin_kinde package which provides a complete middleware solution:

import "github.com/kinde-oss/kinde-go/frameworks/gin_kinde"

func main() {
    router := gin.Default()

    // Set up session middleware
    store := sessions.NewStore(...)
    router.Use(sessions.Sessions("kinde-session", store))

    // Create a protected route group
    privateGroup := router.Group("/")

    // Apply Kinde authentication middleware
    gin_kinde.UseKindeAuth(privateGroup,
        "https://your-tenant.kinde.com",    // Kinde domain
        "your-client-id",                  // Client ID
        "your-client-secret",              // Client secret
        "http://localhost:8080",           // Base redirect URL
        authorization_code.WithPrompt("login"),
        authorization_code.WithOffline(),
    )

    // All routes in privateGroup are now protected
    privateGroup.GET("/profile", func(c *gin.Context) {
        // User is authenticated here
        c.JSON(200, gin.H{"message": "Authenticated!"})
    })

    router.Run(":8080")
}

The gin_kinde.UseKindeAuth middleware:

  1. Initializes the auth flow for each request
  2. Handles the callback at /kinde/callback automatically
  3. Protects all routes in the group by checking authentication
  4. Redirects unauthenticated users to the authorization URL
  5. Provides the Kinde client in the Gin context for additional operations
Custom Middleware Implementation

You can create custom middleware for other frameworks or specific use cases:

func AuthMiddleware(kindeFlow *authorization_code.AuthorizationCodeFlow) func(http.Handler) http.Handler {
    return func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // Check if user is authenticated
            isAuthenticated, err := kindeFlow.IsAuthenticated(r.Context())
            if err != nil || !isAuthenticated {
                // Redirect to authorization URL
                http.Redirect(w, r, kindeFlow.GetAuthURL(), http.StatusFound)
                return
            }

            // User is authenticated, continue to next handler
            next.ServeHTTP(w, r)
        })
    }
}

// Usage with standard http package
func main() {
    kindeFlow, _ := authorization_code.NewAuthorizationCodeFlow(...)

    mux := http.NewServeMux()
    mux.HandleFunc("/protected", protectedHandler)

    // Apply middleware
    handler := AuthMiddleware(kindeFlow)(mux)

    http.ListenAndServe(":8080", handler)
}
Middleware Features

All middleware implementations provide:

  • Automatic authentication checking on protected routes
  • Seamless redirects to the authorization server
  • Session management integration
  • Token validation and refresh handling
  • Error handling with appropriate HTTP status codes
Middleware Configuration Options

When setting up middleware, you can pass the same options used in the authorization flow:

gin_kinde.UseKindeAuth(privateGroup,
    kindeDomain,
    clientID,
    clientSecret,
    baseRedirectURL,
    authorization_code.WithOffline(),                    // Enable refresh tokens
    authorization_code.WithAudience("your-api"),        // Request specific audience
    authorization_code.WithPKCE(),                      // Enable PKCE for public clients
    authorization_code.WithTokenValidation(true),       // Enable token validation
)

These options are automatically applied to the authorization flow created by the middleware.

Session Management

Both flows require session hooks to be implemented for token storage and retrieval. The session hooks interface allows you to customize how tokens are stored and retrieved based on your application's needs.

Token Validation

Both flows support comprehensive token validation options:

  • Signature Validation: Validates token signatures using JWKS
  • Algorithm Validation: Ensures tokens use the expected algorithm (e.g., RS256)
  • Audience Validation: Confirms tokens include the correct API audience
  • Custom Validation: Additional validation rules can be implemented

Offline Support

When using WithOffline(), the flows will:

  • Request offline scope from the authorization server
  • Manage refresh tokens automatically
  • Maintain long-term sessions
  • Automatically refresh expired access tokens

Examples

For complete examples demonstrating these flows, see the examples/ directory in the main repository:

  • Gin Chat Example: Shows how to integrate authorization code flow with a Gin web application
  • CLI Example: Demonstrates device authorization flow with secure token storage

Security Considerations

  • Always use HTTPS in production
  • Implement proper session management
  • Store tokens securely using the provided session hooks
  • Validate tokens on each request
  • Implement proper logout procedures
  • Use appropriate scopes and audiences for your application

Dependencies

This package requires Go 1.24+ and depends on the following packages:

  • github.com/kinde-oss/kinde-go/jwt - For JWT token handling and validation
  • Standard Go packages: context, net/http, oauth2

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExampleCustomMiddleware added in v0.1.3

func ExampleCustomMiddleware(next http.Handler) http.Handler

ExampleCustomMiddleware shows how to create custom middleware that uses the token

func ExampleMiddlewareUsage added in v0.1.3

func ExampleMiddlewareUsage()

ExampleMiddlewareUsage demonstrates how to use the new middleware

func TokenFromContext added in v0.1.3

func TokenFromContext(ctx context.Context) (*jwt.Token, bool)

TokenFromContext extracts the Kinde token from the request context This is a helper function for downstream handlers to access the token

Types

type AuthorizationCodeFlow

type AuthorizationCodeFlow struct {
	JWKS_URL string
	// contains filtered or unexported fields
}

AuthorizationCodeFlow represents the authorization code flow.

func (*AuthorizationCodeFlow) AuthorizationCodeReceivedHandler added in v0.0.5

func (flow *AuthorizationCodeFlow) AuthorizationCodeReceivedHandler(w http.ResponseWriter, r *http.Request)

AuthorizationCodeReceivedHandler handles the callback from the authorization server.

func (*AuthorizationCodeFlow) ExchangeCode

func (flow *AuthorizationCodeFlow) ExchangeCode(ctx context.Context, authorizationCode string, receivedState string) error

Exchanges the authorization code for a token and established KindeContext

func (*AuthorizationCodeFlow) ExchangeDeviceAccessToken added in v0.0.3

func (flow *AuthorizationCodeFlow) ExchangeDeviceAccessToken(ctx context.Context, da *oauth2.DeviceAuthResponse, opts ...oauth2.AuthCodeOption) error

ExchangeDeviceAccessToken retrieves the access token for the device authorization flow.

func (*AuthorizationCodeFlow) GetAuthURL

func (flow *AuthorizationCodeFlow) GetAuthURL() string

Returns the URL to redirect the user to start authentication pipeline.

func (*AuthorizationCodeFlow) GetClient

func (flow *AuthorizationCodeFlow) GetClient(ctx context.Context) (*http.Client, error)

Returns the client to make requests to the backend, will refresh token if offline is requested.

func (*AuthorizationCodeFlow) GetToken added in v0.0.3

func (flow *AuthorizationCodeFlow) GetToken(ctx context.Context) (*jwt.Token, error)

func (*AuthorizationCodeFlow) InjectTokenMiddleware added in v0.1.3

func (flow *AuthorizationCodeFlow) InjectTokenMiddleware(next http.Handler) http.Handler

InjectTokenMiddleware injects the token into the request context for downstream handlers

func (*AuthorizationCodeFlow) IsAuthenticated added in v0.0.3

func (flow *AuthorizationCodeFlow) IsAuthenticated(ctx context.Context) (bool, error)

func (*AuthorizationCodeFlow) Logout added in v0.0.3

func (flow *AuthorizationCodeFlow) Logout() error

func (*AuthorizationCodeFlow) StartDeviceAuth added in v0.0.3

func (flow *AuthorizationCodeFlow) StartDeviceAuth(ctx context.Context) (*oauth2.DeviceAuthResponse, error)

StartDeviceAuth retrieves the device authorization response. It returns the device authorization response or an error if the request fails. This is used for the device authorization flow.

type IAuthorizationCodeFlow added in v0.0.4

type IAuthorizationCodeFlow interface {
	// Logout clears the session and token.
	GetAuthURL() string
	// Exchanges the authorization code for a token and establishes KindeContext.
	ExchangeCode(ctx context.Context, authorizationCode string, receivedState string) error
	// Returns http client to call external services, will refresh token behind the scenes if offline is requested.
	GetClient(ctx context.Context) (*http.Client, error)
	// Check if user is authenticated.
	IsAuthenticated(context.Context) (bool, error)
	// Clears local tokens and logs user out.
	Logout() error
	// A helper handler middleware for the code exchanger
	AuthorizationCodeReceivedHandler(w http.ResponseWriter, r *http.Request)
	// InjectTokenMiddleware that injects the token into the request context
	InjectTokenMiddleware(next http.Handler) http.Handler
}

IAuthorizationCodeFlow represents the interface for the authorization code flow.

func NewAuthorizationCodeFlow

func NewAuthorizationCodeFlow(baseURL string, clientID string, clientSecret string, callbackURL string,
	options ...Option) (IAuthorizationCodeFlow, error)

Creates a new AuthorizationCodeFlow with the given baseURL, clientID, clientSecret and options to authenticate backend applications.

type IDeviceAuthorizationFlow added in v0.0.4

type IDeviceAuthorizationFlow interface {
	// StartDeviceAuth starts the device authorization flow.
	StartDeviceAuth(ctx context.Context) (*oauth2.DeviceAuthResponse, error)
	// Exchanges the device code to access token.
	ExchangeDeviceAccessToken(ctx context.Context, da *oauth2.DeviceAuthResponse, opts ...oauth2.AuthCodeOption) error
	// Returns http client to call external services, will refresh token behind the scenes if offline is requested.
	GetClient(ctx context.Context) (*http.Client, error)
	// Checks if the user is authenticated.
	IsAuthenticated(context.Context) (bool, error)
	// Clears local tokens and logs user out.
	Logout() error
	// Returns the token for the current session.
	GetToken(context.Context) (*jwt.Token, error)
}

IDeviceAuthorizationFlow represents the interface for the device authorization flow.

func NewDeviceAuthorizationFlow added in v0.0.3

func NewDeviceAuthorizationFlow(baseURL string, options ...Option) (IDeviceAuthorizationFlow, error)

Creates a new AuthorizationCodeFlow with the given baseURL, clientID, clientSecret and options to authenticate backend applications.

type ISessionHooks added in v0.0.4

type ISessionHooks interface {
	// SetRawToken stores the raw token in the session.
	SetRawToken(token *oauth2.Token) error
	// GetRawToken retrieves the raw token from the session.
	GetRawToken() (*oauth2.Token, error)
	// GetState retrieves the state from the session.
	GetState() (string, error)
	// SetState sets the state in the session.
	SetState(state string) error
	// SetPostAuthRedirect sets the post-authentication redirect URL in the session.
	SetPostAuthRedirect(redirect string) error
	// GetPostAuthRedirect retrieves the post-authentication redirect URL from the session.
	GetPostAuthRedirect() (string, error)
	// SetCodeVerifier stores the PKCE code verifier in the session.
	SetCodeVerifier(codeVerifier string) error
	// GetCodeVerifier retrieves the PKCE code verifier from the session.
	GetCodeVerifier() (string, error)
}

ISessionHooks defines the interface for session management in the authorization code flow.

type Option added in v0.0.4

type Option func(*AuthorizationCodeFlow)

func WithAdditionalScope added in v0.0.3

func WithAdditionalScope(scope string) Option

Adds a scopes to the list of scopes to request, adds scope to existing list.

func WithAudience

func WithAudience(audience string) Option

Adds an audience to the list of audiences to request.

func WithAuthParameter

func WithAuthParameter(name, value string) Option

Adds an arbitrary parameter to the list of parameters to request.

func WithClientID added in v0.0.3

func WithClientID(clientID string) Option

Integrates with the session management

func WithClientSecret added in v0.0.3

func WithClientSecret(clientSecret string) Option

Integrates with the session management

func WithCustomStateGenerator

func WithCustomStateGenerator(stateFunc func(*AuthorizationCodeFlow) string) Option

Adds the offline scope to the list of scopes to request.

func WithOffline

func WithOffline() Option

Adds the offline scope to the list of scopes to request.

func WithPKCE added in v0.1.2

func WithPKCE() Option

Enables PKCE (Proof Key for Code Exchange) for enhanced security in public clients. This is recommended for applications that cannot securely store a client secret.

func WithPKCEChallengeMethod added in v0.1.2

func WithPKCEChallengeMethod(method string) Option

func WithPrompt added in v0.0.3

func WithPrompt(prompt string) Option

Adds an audience to the list of audiences to request.

func WithScopes added in v0.0.3

func WithScopes(scopes ...string) Option

Adds a scopes to the list of scopes to request, replaces value with the provided.

func WithSessionHooks

func WithSessionHooks(sessionHooks ISessionHooks) Option

Integrates with the session management

func WithTokenValidation

func WithTokenValidation(isValidateJWKS bool, tokenOptions ...func(*jwt.Token)) Option

Adds options to validate the token.

Jump to

Keyboard shortcuts

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