PHP发送outlook(微软)OAuth 2.0企业版邮箱验证码

一、准备工作:

  1. 登录Azure 门户,使用企业版 Microsoft 365 管理员账号(或拥有应用注册权限的账号)登录。
  2. 在左侧导航栏搜索并进入「Azure Active Directory」→ 「应用注册」→ 「新注册」。
  3. 填写应用注册信息:
    • 名称:自定义(如「PHPMailer-Office365 - 邮件发送」)
    • 支持的账户类型:选择「仅此组织目录中的账户(你的企业域名 - 单一租户)」(企业版专属,更安全)
    • 重定向 URI:选择「Web」,填写你的应用回调地址(如https://你的域名/oauth-callback.php,后续需创建该回调文件)
  4. 注册完成后,记录核心参数(后续代码需使用):
    • 应用(客户端)ID:即client_id
    • 目录(租户)ID:即tenant_id
  5. 配置应用权限:
    • 进入该应用 → 「API 权限」→ 「添加权限」→ 搜索并选择「Microsoft Graph」(注意:不是 Outlook SMTP,OAuth 2.0 依赖 Microsoft Graph API)
    • 选择「应用权限」(后台发送邮件无需用户交互,优先选择;若需用户授权后发送,选择「委托权限」)
    • 勾选 Mail.Send(发送邮件的核心权限)→ 「添加权限」
    • 点击「授予管理员同意(你的企业域名)」(必须完成此步骤,否则权限不生效)
  6. 创建客户端密码:
    • 进入该应用 → 「证书和密码」→ 「客户端密码」→ 「新建客户端密码」
    • 填写描述、选择有效期 → 「添加」
    • 立即记录密码值(即client_secret,仅显示一次,关闭页面后无法再查看)

完成以上步骤即可获得

Tenant ID(租户ID):5f567e67-********-f94036056090

Client ID(应用 ID):a5a85bb5-********-f97a545f19f5

Client Secret(应用密钥):Yrs8Q~aXO6ju2T-********_NCeUtcn6

用来获取发送邮件时的access_token

二、安装扩展

php 复制代码
# 阿里云镜像(推荐,速度最快)
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
# 然后再执行依赖安装命令
composer require phpmailer/phpmailer league/oauth2-client

三、完整代码

php 复制代码
<?php
require '../api/vendor/autoload.php';
use League\OAuth2\Clsient\Provider\Exception\IdentityProviderException;

// 配置参数
$TenantId = '';//Tenant ID(租户ID)
$clientId = '';//Client ID(应用 ID)
$clientSecret = '';//Client Secret(应用密钥)
$fromEmail = '';//发送邮箱
$toEmail = '';//目标邮箱

// 1. 用客户端凭证流获取Access Token(无需refresh_token)
$tokenUrl = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token";
$postData = [
    'grant_type' => 'client_credentials',
    'client_id' => $clientId,
    'client_secret' => $clientSecret,
    'scope' => 'https://graph.microsoft.com/.default'
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => $tokenUrl,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query($postData),
    CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded']
]);
$tokenResponse = json_decode(curl_exec($ch), true);
curl_close($ch);

if (!isset($tokenResponse['access_token'])) {
    echo "Token获取失败:" . json_encode($tokenResponse) . "\n";
    exit;
}
$token = $tokenResponse['access_token'];

// 2. 调用Graph API发送邮件
$mailData = [
    'message' => [
        'subject' => '【登录验证码】',
        'body' => ['contentType' => 'HTML', 'content' => '测试发送'],
        'toRecipients' => [['emailAddress' => ['address' => $toEmail]]],
        'from' => ['emailAddress' => ['address' => $fromEmail]]
    ],
    'saveToSentItems' => true
];

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => "https://graph.microsoft.com/v1.0/users/$fromEmail/sendMail",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode($mailData),
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer $token",
        "Content-Type: application/json"
    ]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpCode === 202) {
    echo "邮件发送成功!";
} else {
    $error = json_decode($response, true);
    echo "失败原因:" . ($error['error']['message'] ?? '未知错误') . "\n";
}

四、关键前提(必须满足)

无论用哪种方式,都需要:

  1. Azure 应用已添加Mail.Send权限(应用权限,不是委派权限)

  2. 全局管理员已点击 "授予管理员同意"

  3. 发件人邮箱($fromEmail )属于该 Azure 租户

相关推荐
BingoGo6 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack6 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack1 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1234 天前
matlab画图工具
开发语言·matlab
dustcell.4 天前
haproxy七层代理
java·开发语言·前端