Provider 模块¶
pkg/provider 模块负责处理各个 AI 服务厂商的非标 OAuth 鉴权及会话生命周期管理。有别于可以直接通过 API Key 裸调用的服务,部分企业级平台(如 Gemini、Qwen 网页端模型接入、MiniMax 云端应用)要求使用标准的 OAuth2 授权码流程(Authorization Code Flow)或设备流(Device Flow)来获取具有时效性的 Access Token。该模块正是为此痛点提供的一站式解决方案。
核心功能¶
- OAuth2 授权流适配
- 设备流 (Device Flow): 针对 Qwen 等平台,利用
RequestDeviceCode获取用户设备验证码,并在终端轮询(PollForToken)等待用户于网页端授权完成,从而换取 Token。 -
本地回调流 (Local Callback Server): 针对 Gemini 等标准 OAuth 平台,程序可在本地端口启动一个短暂的 HTTP 回调服务器,接收浏览器重定向带来的
code从而安全完成授权交互。 -
PKCE (Proof Key for Code Exchange) 安全增强 内置了
core.PKCEHelper的应用集成,自动生成安全的高强度动态加密状态校验机,防范针对公共客户端的 CSRF 与鉴权劫持攻击。 -
刷新与长连接管理 暴露通用的
RefreshTokenAPI。它能够通过原有的 Refresh Token 与提供商进行安全换绑,实现无需用户重复扫码扫页面的持久化访问体验。
内部架构设计¶
该模块下的具体实现(如 GeminiProvider, QwenProvider, MiniMaxProvider)不强制实现某个特定的单一接口,但其功能模式均围绕获取并返回 core.OAuthToken 对象展开。所有的状态变更都会委托给位于 pkg/core 的 AuthManager(认证管理器)或 TokenStore(令牌存储设施)进行持久化写入。
详细使用方法¶
以 Qwen Provider 设备授权流为例:
package main
import (
"fmt"
"github.com/DotNetAge/gochat/pkg/core"
"github.com/DotNetAge/gochat/pkg/provider"
)
func main() {
// 1. 初始化特定的 Provider
qwenProvider := provider.NewQwenProvider()
// 2. 结合 AuthManager 并指定凭证持久化的目标文件
// AuthManager 会自动接管过期检测、Token 获取及持久化存储
authManager := core.NewAuthManager(qwenProvider, "qwen_auth_token.json")
// 3. 尝试直接获取已保存的 Token
token, err := authManager.GetToken()
if err != nil {
fmt.Println("未找到有效凭证,开始全新的 OAuth 设备流鉴权...")
// 4. 调用 Login 会在控制台打印提示指引,并进入轮询等待
if err := authManager.Login(); err != nil {
panic(err)
}
// 鉴权成功后,重新获取即可
token, _ = authManager.GetToken()
}
fmt.Printf("成功获取 Access Token: %s\n", token.Access[:10]+"***")
fmt.Printf("Token 将在 Unix Timestamp(ms): %d 时过期\n", token.Expires)
// 后续可以将 token.Access 作为 Bearer 注入到 Client 发起 LLM 对话请求
}
实现基本原理与设计优点¶
在使用 OAuth 的 Device Flow 时,厂商往往会限制轮询请求的频率(如抛出 slow_down 错误)。在 QwenProvider 与 MiniMaxProvider 内部,均通过带有退避倍数的等待机制平滑地应对了这些特殊的网络限流阻断行为。极大降低了在 CLI 或后台 Agent 环境下构建基于身份验证调用的难度。