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 租户

相关推荐
.简.简.单.单.2 小时前
Design Patterns In Modern C++ 中文版翻译 第九章 装饰器
开发语言·c++·设计模式
钟智强2 小时前
红队实战复盘:如何运用【火尖枪】高效突破复杂登录防线
服务器·安全·web安全·http·go·php·bruteforce
Hard but lovely2 小时前
Linux: posix标准:线程互斥&& 互斥量的原理&&抢票问题
linux·开发语言
好记忆不如烂笔头abc2 小时前
安装python新版本
开发语言·人工智能·python
JaguarJack2 小时前
成为高级 PHP 开发者需要的思维转变
后端·php·服务端
csbysj20202 小时前
HTML 音频(Audio)
开发语言
枫叶丹42 小时前
【Qt开发】Qt事件(三)-> QMouseEvent 鼠标事件
c语言·开发语言·c++·qt·microsoft·计算机外设
BingoGo2 小时前
成为高级 PHP 开发者需要的思维转变
后端·php
Leonardo_Fibonacci2 小时前
skbbs-day5
java·开发语言·mybatis