ASP.NET Core Web API调用Gmail API通过Google Workspace发邮件报错400
错误原因
- 未为服务账号开启Google Workspace全域委托权限:服务账号本身没有Gmail邮箱权限,必须开启全域委托才能模拟Workspace内的真实用户发信
- 未给服务账号授予Gmail API发送权限:需要在Google Workspace管理后台为服务账号分配
https://www.googleapis.com/auth/gmail.send作用域 - 代码未指定要模拟的用户:你的代码初始化
ServiceAccountCredential时没有绑定要模拟的Workspace发件人邮箱,服务账号无法直接调用Gmail接口 - 邮件Raw字段赋值逻辑错误:
SignBlobAsync是用于JWT签名的方法,Gmail要求的Raw字段是邮件内容经过Base64Url编码后的字符串,不是签名结果
前置配置步骤
- 进入Google Cloud控制台,打开当前项目的API库,搜索并启用Gmail API
- 进入「服务账号」页面,创建服务账号后下载JSON格式的密钥文件,重命名为
credentials.json放入项目根目录,设置文件的「复制到输出目录」属性为「如果较新则复制」 - 进入Google Workspace管理后台,依次打开「安全」→「访问和数据控制」→「API控制」→「全域委派」,添加新的客户端:
- 客户端ID填写你服务账号的客户端ID(可在Google Cloud控制台服务账号详情页查看)
- OAuth作用域填写
https://www.googleapis.com/auth/gmail.send,保存后等待10-15分钟生效
正确实现代码
首先安装所需NuGet包:
Install-Package Google.Apis.Gmail.v1 Install-Package Google.Apis.Auth Install-Package MimeKit
发信逻辑代码:
using Google.Apis.Auth.OAuth2; using Google.Apis.Gmail.v1; using Google.Apis.Services; using MimeKit; using System.Net.Mail; // 配置参数 const string ApplicationName = "你的应用名称"; const string SenderEmail = "你的Google Workspace发件人邮箱(必须是域内真实用户)"; const string CredentialsPath = "credentials.json"; // 初始化带用户模拟的服务账号凭证 ServiceAccountCredential credential; using (var stream = new FileStream(CredentialsPath, FileMode.Open, FileAccess.Read)) { credential = ServiceAccountCredential.FromServiceAccountData(stream) // 核心:指定要模拟的发件人用户 .CreateWithUser(SenderEmail); // 授权发送邮件的作用域 credential.Scopes = new[] { GmailService.Scope.GmailSend }; } // 初始化Gmail服务 var service = new GmailService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = ApplicationName, }); // 构建邮件内容 var mailMessage = new MailMessage(SenderEmail, destinationEmailAddress, "Verification code", $"Your verification code is {messageBody}"); var mimeMessage = MimeMessage.CreateFromMailMessage(mailMessage); // 生成符合Gmail要求的Raw字段 byte[] emailBytes; using (var memoryStream = new MemoryStream()) { mimeMessage.WriteTo(memoryStream); emailBytes = memoryStream.ToArray(); } // Base64Url编码处理 var rawEmail = Convert.ToBase64String(emailBytes) .Replace('+', '-') .Replace('/', '_') .TrimEnd('='); // 发送邮件 var message = new Google.Apis.Gmail.v1.Data.Message { Raw = rawEmail }; await service.Users.Messages.Send(message, "me").ExecuteAsync();
内容的提问来源于stack exchange,提问作者Sein Gerivani
相关产品推荐
相关产品推荐

