Skip to content

Provider Module

The pkg/provider module is responsible for handling non-standard OAuth authentication and session lifecycle management for various AI service vendors. Unlike services that can be called directly with API Key, some enterprise platforms (such as Gemini, Qwen web model access, MiniMax cloud applications) require using the standard OAuth2 authorization code flow (Authorization Code Flow) or device flow (Device Flow) to obtain time-sensitive Access Tokens. This module is a one-stop solution for this pain point.

Core Features

  1. OAuth2 Authorization Flow Adaptation
  2. Device Flow: For platforms like Qwen, use RequestDeviceCode to get the user device verification code, and poll (PollForToken) in the terminal waiting for user authorization completion on the web page to exchange for Token.
  3. Local Callback Flow: For standard OAuth platforms like Gemini, the program can start a short-lived HTTP callback server on a local port to receive the code brought by browser redirects, safely completing the authorization interaction.

  4. PKCE (Proof Key for Code Exchange) Security Enhancement Built-in core.PKCEHelper application integration, automatically generating secure high-strength dynamic cryptographic state validators to prevent CSRF and authentication hijacking attacks against public clients.

  5. Refresh and Long-Connection Management Exposes a generic RefreshToken API. It can securely rebind with the provider through the original Refresh Token, achieving persistent access experience without requiring users to repeatedly scan codes or pages.

Internal Architecture Design

Specific implementations under this module (such as GeminiProvider, QwenProvider, MiniMaxProvider) do not mandate implementing a single specific interface, but their functional patterns all revolve around obtaining and returning core.OAuthToken objects. All state changes are delegated to the AuthManager (authentication manager) or TokenStore (token storage facility) located in pkg/core for persistent writes.

Detailed Usage Examples

Taking the Qwen Provider device authorization flow as an example:

package main

import (
    "fmt"
    "github.com/DotNetAge/gochat/pkg/core"
    "github.com/DotNetAge/gochat/pkg/provider"
)

func main() {
    // 1. Initialize specific Provider
    qwenProvider := provider.NewQwenProvider()

    // 2. Combine with AuthManager and specify the target file for credential persistence
    // AuthManager will automatically take over expiration detection, Token acquisition, and persistent storage
    authManager := core.NewAuthManager(qwenProvider, "qwen_auth_token.json")

    // 3. Try to directly get the saved Token
    token, err := authManager.GetToken()

    if err != nil {
        fmt.Println("No valid credentials found, starting a brand new OAuth device flow authentication...")

        // 4. Calling Login will print prompts in the console and enter polling wait
        if err := authManager.Login(); err != nil {
            panic(err)
        }

        // After successful authentication, get it again
        token, _ = authManager.GetToken()
    }

    fmt.Printf("Successfully obtained Access Token: %s\n", token.Access[:10]+"***")
    fmt.Printf("Token will expire at Unix Timestamp(ms): %d\n", token.Expires)

    // Later, you can inject token.Access as Bearer into Client to initiate LLM chat request
}

Implementation Principles and Design Advantages

When using OAuth's Device Flow, vendors often limit the frequency of polling requests (such as throwing slow_down errors). Internally, both QwenProvider and MiniMaxProvider smoothly handle these special network rate-limiting blocking behaviors through a wait mechanism with backoff multipliers. This greatly reduces the difficulty of building identity-verified calls in CLI or backend Agent environments.