You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET/C#实现Gmail OAuth 2.0邮件认证的方案咨询

C#/VB.NET 桌面应用对接Gmail OAuth2.0 单账号实现方案

适用于仅使用固定单个Gmail账号发信、不需要对接其他Google API的Windows桌面场景,无需依赖重型Google SDK


前置配置

  • 进入Google Cloud控制台新建项目,搜索启用Gmail API
  • 打开OAuth同意屏幕配置页,用户类型选「外部」,填写基础应用信息后,在测试用户列表添加你要使用的目标Gmail账号
    个人自用单账号场景不需要提交Google应用审核,添加测试账号即可正常使用,无额外调用限制
  • 进入凭证创建页,新建OAuth2.0客户端ID,应用类型选择「桌面应用」,创建完成后保存生成的客户端ID、客户端密钥
  • 授权范围按需选择:仅发信填https://www.googleapis.com/auth/gmail.send,需要收信+发信填https://mail.google.com/

核心实现逻辑

单固定账号场景不需要做复杂的多用户交互、每次弹浏览器授权:

  1. 首次运行一次临时授权流程,拿到长期有效的刷新令牌,永久存储到本地即可
  2. 后续程序每次需要连接Gmail服务时,用刷新令牌向Google令牌接口请求1小时有效期的访问令牌,直接传给邮件组件走XOAUTH2认证即可,和原有账号密码登录的流程体验基本一致

可直接复用的代码

所有代码基于原生HttpClient实现,无额外强制依赖,JSON解析可以用你项目里已有的JSON库,不需要额外装包。

日常运行用:刷新令牌换访问令牌(无交互)

VB.NET 版本

Imports System.Net.Http
Imports System.Collections.Generic
Imports System.Text
' 如果你项目里没有JSON解析库,可以手动拆分响应字符串拿access_token,不需要强制装Newtonsoft.Json
Imports Newtonsoft.Json

Public Class GmailOAuthHelper
    ' 以下三个值替换成你自己配置拿到的内容
    Private Const ClientId As String = "你的OAuth客户端ID"
    Private Const ClientSecret As String = "你的OAuth客户端密钥"
    Private Const SavedRefreshToken As String = "首次授权拿到的永久刷新令牌"
    Private Shared ReadOnly _httpClient As New HttpClient()

    Public Shared Async Function GetGmailAccessTokenAsync() As Task(Of String)
        Dim requestParams = New Dictionary(Of String, String) From {
            {"client_id", ClientId},
            {"client_secret", ClientSecret},
            {"refresh_token", SavedRefreshToken},
            {"grant_type", "refresh_token"}
        }
        Dim response = Await _httpClient.PostAsync(
            "https://oauth2.googleapis.com/token",
            New FormUrlEncodedContent(requestParams)
        )
        response.EnsureSuccessStatusCode()
        Dim responseContent = Await response.Content.ReadAsStringAsync()
        Dim tokenResult = JsonConvert.DeserializeObject(Of TokenResponse)(responseContent)
        Return tokenResult.access_token
    End Function

    Private Class TokenResponse
        Public Property access_token As String
        Public Property expires_in As Integer
        Public Property token_type As String
        Public Property refresh_token As String
    End Class
End Class

C# 版本

using System.Net.Http;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;

public class GmailOAuthHelper
{
    // 以下三个值替换成你自己配置拿到的内容
    private const string ClientId = "你的OAuth客户端ID";
    private const string ClientSecret = "你的OAuth客户端密钥";
    private const string SavedRefreshToken = "首次授权拿到的永久刷新令牌";
    private static readonly HttpClient _httpClient = new HttpClient();

    public static async Task<string> GetGmailAccessTokenAsync()
    {
        var requestParams = new Dictionary<string, string>
        {
            {"client_id", ClientId},
            {"client_secret", ClientSecret},
            {"refresh_token", SavedRefreshToken},
            {"grant_type", "refresh_token"}
        };
        var response = await _httpClient.PostAsync(
            "https://oauth2.googleapis.com/token",
            new FormUrlEncodedContent(requestParams)
        );
        response.EnsureSuccessStatusCode();
        var responseContent = await response.Content.ReadAsStringAsync();
        var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(responseContent);
        return tokenResult.access_token;
    }

    private class TokenResponse
    {
        public string access_token { get; set; }
        public int expires_in { get; set; }
        public string token_type { get; set; }
        public string refresh_token { get; set; }
    }
}

一次性用:首次授权拿刷新令牌

这段逻辑不需要写到正式发布的程序里,单独建个临时控制台项目跑一次,拿到refresh_token存下来就可以删掉,避免给正式项目加多余逻辑:

Imports System.Net
Imports System.Diagnostics

' 放在GmailOAuthHelper类里即可
Public Shared Async Function GetRefreshTokenOneTimeAsync() As Task(Of String)
    Dim redirectUri = "http://localhost:9000"
    ' 构造授权URL,必须加access_type=offline&prompt=consent才会返回刷新令牌
    Dim authUrl = $"https://accounts.google.com/o/oauth2/v2/auth?client_id={Uri.EscapeDataString(ClientId)}&redirect_uri={Uri.EscapeDataString(redirectUri)}&response_type=code&scope={Uri.EscapeDataString("https://mail.google.com/")}&access_type=offline&prompt=consent"
    ' 打开系统默认浏览器跳授权页
    Process.Start(New ProcessStartInfo(authUrl) With {.UseShellExecute = True})
    ' 临时监听本地端口拿Google回调的授权码
    Dim listener = New HttpListener()
    listener.Prefixes.Add($"{redirectUri}/")
    listener.Start()
    Dim context = Await listener.GetContextAsync()
    Dim authCode = context.Request.QueryString("code")
    ' 给浏览器返回成功提示
    Dim successPage = Encoding.UTF8.GetBytes("<html><body style='padding:40px;font-size:18px'>授权完成,可以关闭当前页面</body></html>")
    context.Response.ContentType = "text/html; charset=utf-8"
    context.Response.ContentLength64 = successPage.Length
    Await context.Response.OutputStream.WriteAsync(successPage, 0, successPage.Length)
    context.Response.Close()
    listener.Stop()
    ' 用授权码换令牌
    Dim tokenRequestParams = New Dictionary(Of String, String) From {
        {"code", authCode},
        {"client_id", ClientId},
        {"client_secret", ClientSecret},
        {"redirect_uri", redirectUri},
        {"grant_type", "authorization_code"}
    }
    Dim tokenResponse = Await _httpClient.PostAsync(
        "https://oauth2.googleapis.com/token",
        New FormUrlEncodedContent(tokenRequestParams)
    )
    tokenResponse.EnsureSuccessStatusCode()
    Dim tokenContent = Await tokenResponse.Content.ReadAsStringAsync()
    Dim tokenResult = JsonConvert.DeserializeObject(Of TokenResponse)(tokenContent)
    ' 这里拿到的refresh_token就是永久有效的,存到代码/配置里即可
    Return tokenResult.refresh_token
End Function

对接现有IMapX组件注意事项

  • 认证时用户名依然填完整的Gmail邮箱地址,和之前的配置一致
  • 原来填写Gmail应用密码的位置,替换成GetGmailAccessTokenAsync()返回的访问令牌
  • 组件认证模式选择XOAUTH2,如果IMapX没有提供显式的XOAUTH2选项,可以手动拼接标准XOAUTH2认证串转Base64传入,格式为:user={你的完整Gmail地址} + Chr(1) + auth=Bearer {访问令牌} + Chr(1) + Chr(1)
  • 访问令牌有效期为1小时,不需要频繁刷新,程序启动时刷一次、或者每次发信前判断过期时间刷新即可
  • 只要不手动在Google账号安全设置里撤销应用授权,刷新令牌永久有效,不需要重复走授权流程

内容的提问来源于stack exchange,提问作者Derpopotumus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 11:39:18