一、准备工作:
- 登录Azure 门户,使用企业版 Microsoft 365 管理员账号(或拥有应用注册权限的账号)登录。
- 在左侧导航栏搜索并进入「Azure Active Directory」→ 「应用注册」→ 「新注册」。
- 填写应用注册信息:
- 名称:自定义(如「PHPMailer-Office365 - 邮件发送」)
- 支持的账户类型:选择「仅此组织目录中的账户(你的企业域名 - 单一租户)」(企业版专属,更安全)
- 重定向 URI:选择「Web」,填写你的应用回调地址(如
https://你的域名/oauth-callback.php,后续需创建该回调文件)
- 注册完成后,记录核心参数(后续代码需使用):
- 应用(客户端)ID:即
client_id - 目录(租户)ID:即
tenant_id
- 应用(客户端)ID:即
- 配置应用权限:
- 进入该应用 → 「API 权限」→ 「添加权限」→ 搜索并选择「Microsoft Graph」(注意:不是 Outlook SMTP,OAuth 2.0 依赖 Microsoft Graph API)
- 选择「应用权限」(后台发送邮件无需用户交互,优先选择;若需用户授权后发送,选择「委托权限」)
- 勾选
Mail.Send(发送邮件的核心权限)→ 「添加权限」 - 点击「授予管理员同意(你的企业域名)」(必须完成此步骤,否则权限不生效)
- 创建客户端密码:
- 进入该应用 → 「证书和密码」→ 「客户端密码」→ 「新建客户端密码」
- 填写描述、选择有效期 → 「添加」
- 立即记录密码值(即
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";
}
四、关键前提(必须满足)
无论用哪种方式,都需要:
-
Azure 应用已添加
Mail.Send权限(应用权限,不是委派权限) -
全局管理员已点击 "授予管理员同意"
-
发件人邮箱($fromEmail )属于该 Azure 租户
