Skip to content
本页内容由 AI 辅助生成与翻译,如有不当之处,欢迎协助改进。 在 GitHub 上编辑

OAuth 认证

PRX-Email 通过 XOAUTH2 机制支持 IMAP 和 SMTP 的 OAuth 2.0 认证。这是 Outlook/Office 365 的必要条件,也是 Gmail 的推荐方式。插件提供令牌过期追踪、可插拔刷新提供者和基于环境变量的热重载。

XOAUTH2 工作原理

XOAUTH2 用 OAuth 访问令牌替代传统密码认证。客户端在 IMAP AUTHENTICATE 或 SMTP AUTH 期间发送特定格式的字符串:

user=<email>\x01auth=Bearer <access_token>\x01\x01

设置 auth.oauth_token 后 PRX-Email 自动处理此过程。

Gmail OAuth 设置

1. 创建 Google Cloud 凭据

  1. 前往 Google Cloud Console
  2. 创建项目或选择现有项目
  3. 启用 Gmail API
  4. 创建 OAuth 2.0 凭据(桌面应用类型)
  5. 记录客户端 ID客户端密钥

2. 获取访问令牌

使用 Google OAuth Playground 或自己的 OAuth 流程获取具有以下范围的访问令牌:

  • https://mail.google.com/(完整 IMAP/SMTP 访问)

3. 配置 PRX-Email

rust
use prx_email::plugin::{AuthConfig, ImapConfig, SmtpConfig};

let auth = AuthConfig {
    password: None,
    oauth_token: Some("ya29.your-access-token-here".to_string()),
};

let imap = ImapConfig {
    host: "imap.gmail.com".to_string(),
    port: 993,
    user: "[email protected]".to_string(),
    auth: auth.clone(),
};

let smtp = SmtpConfig {
    host: "smtp.gmail.com".to_string(),
    port: 465,
    user: "[email protected]".to_string(),
    auth,
};

Outlook OAuth 设置

PRX-Email 包含一个 Outlook/Office 365 OAuth 引导脚本,处理完整的授权码流程。

1. 注册 Azure 应用

  1. 前往 Azure 门户应用注册
  2. 注册新应用
  3. 设置重定向 URI(如 http://localhost:53682/callback
  4. 记录应用(客户端)ID目录(租户)ID
  5. 在 API 权限中添加:
    • offline_access
    • https://outlook.office.com/IMAP.AccessAsUser.All
    • https://outlook.office.com/SMTP.Send

2. 运行引导脚本

bash
cd /path/to/prx_email
chmod +x scripts/outlook_oauth_bootstrap.sh

CLIENT_ID='your-azure-client-id' \
TENANT='your-tenant-id-or-common' \
REDIRECT_URI='http://localhost:53682/callback' \
./scripts/outlook_oauth_bootstrap.sh

脚本将:

  1. 打印授权 URL——在浏览器中打开
  2. 等待你粘贴回调 URL 或授权码
  3. 用授权码换取访问令牌和刷新令牌
  4. 保存令牌到 ./outlook_oauth.local.env,权限为 chmod 600

脚本选项

参数说明
--output <file>自定义输出路径(默认:./outlook_oauth.local.env
--dry-run只打印授权 URL 然后退出
-h, --help显示使用帮助

环境变量

变量必填说明
CLIENT_IDAzure 应用客户端 ID
TENANT租户 ID,或 common/organizations/consumers
REDIRECT_URI在 Azure 应用中注册的重定向 URI
SCOPE自定义范围(默认:IMAP + SMTP + offline_access)

安全

永远不要提交生成的令牌文件。将 *.local.env 添加到 .gitignore

令牌生命周期管理

过期追踪

PRX-Email 按协议(IMAP/SMTP)追踪 OAuth 令牌过期时间戳:

rust
// 通过环境变量设置过期时间
std::env::set_var("PRX_EMAIL_IMAP_OAUTH_EXPIRES_AT", "1800000000");
std::env::set_var("PRX_EMAIL_SMTP_OAUTH_EXPIRES_AT", "1800000000");

每次操作前,插件检查令牌是否在 60 秒内过期。如果是,尝试刷新。

可插拔刷新提供者

实现 OAuthRefreshProvider trait 处理自动令牌刷新:

rust
use prx_email::plugin::{
    OAuthRefreshProvider, RefreshedOAuthToken, ApiError, ErrorCode,
};

struct MyRefreshProvider {
    client_id: String,
    client_secret: String,
    refresh_token: String,
}

impl OAuthRefreshProvider for MyRefreshProvider {
    fn refresh_token(
        &self,
        protocol: &str,
        user: &str,
        current_token: &str,
    ) -> Result<RefreshedOAuthToken, ApiError> {
        // 调用 OAuth 提供商的令牌端点
        // 返回新的访问令牌和可选的过期时间
        Ok(RefreshedOAuthToken {
            token: "new-access-token".to_string(),
            expires_at: Some(now + 3600),
        })
    }
}

创建插件时附加提供者:

rust
let plugin = EmailPlugin::new_with_config(repo, config)
    .with_refresh_provider(Box::new(MyRefreshProvider {
        client_id: "...".to_string(),
        client_secret: "...".to_string(),
        refresh_token: "...".to_string(),
    }));

环境变量热重载

运行时重载 OAuth 令牌,无需重启:

rust
// 在环境中设置新令牌
std::env::set_var("PRX_EMAIL_IMAP_OAUTH_TOKEN", "new-imap-token");
std::env::set_var("PRX_EMAIL_SMTP_OAUTH_TOKEN", "new-smtp-token");
std::env::set_var("PRX_EMAIL_IMAP_OAUTH_EXPIRES_AT", "1800003600");
std::env::set_var("PRX_EMAIL_SMTP_OAUTH_EXPIRES_AT", "1800003600");

// 触发重载
plugin.reload_auth_from_env("PRX_EMAIL");

reload_auth_from_env 方法读取给定前缀的环境变量,更新 IMAP/SMTP OAuth 令牌和过期时间戳。加载 OAuth 令牌时会清除对应的密码,以维护"二选一"的认证不变量。

完整配置重载

进行完整的传输重配置:

rust
plugin.reload_config(new_transport_config)?;

这会验证新配置并原子性地替换整个传输配置。

OAuth 环境变量

变量说明
{PREFIX}_IMAP_OAUTH_TOKENIMAP OAuth 访问令牌
{PREFIX}_SMTP_OAUTH_TOKENSMTP OAuth 访问令牌
{PREFIX}_IMAP_OAUTH_EXPIRES_ATIMAP 令牌过期时间(Unix 秒)
{PREFIX}_SMTP_OAUTH_EXPIRES_ATSMTP 令牌过期时间(Unix 秒)

默认前缀为 PRX_EMAIL。使用 reload_auth_from_env("PRX_EMAIL") 在运行时加载。

安全最佳实践

  1. 永不记录令牌。 PRX-Email 清理调试消息并编辑认证相关内容。
  2. 使用刷新令牌。 访问令牌会过期;生产环境务必实现刷新提供者。
  3. 安全存储令牌。 使用文件权限(chmod 600),永不将令牌文件提交到版本控制。
  4. 定期轮换令牌。 即使有自动刷新,也应定期验证令牌正在轮换。

后续步骤

Released under the Apache-2.0 License.