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

相关推荐
luj_17684 小时前
残熵算法实时化三大瓶颈突破
c语言·开发语言·网络·经验分享·算法
不听话坏5 小时前
Ignition篇(下 一) 动态执行前的事情
开发语言·前端·javascript
likeyi075 小时前
require 和 import的区别
开发语言·前端
远离UE46 小时前
UE5 compute shader 原子加
开发语言·c++·ue5
C+-C资深大佬6 小时前
C++ 显式类型转换详解:static_cast、dynamic_cast、const_cast、reinterpret_cast
开发语言·c++
KaMeidebaby7 小时前
卡梅德生物技术快报|抗体亲和力成熟工业化调控新机制:差异性浆细胞增殖工艺优化思路
java·开发语言·人工智能·算法·机器学习·架构·spark
luj_17687 小时前
心形曲线轨迹控制三大关键技术
c语言·开发语言·c++·经验分享·算法
Mininglamp_27188 小时前
Claude Code 封禁中国开发者之后:本地 AI 编程工具的替代方案实测
开发语言·人工智能·windows·开源软件·ai-native
思麟呀8 小时前
C++17(三)if constexpr+折叠表达式
开发语言·c++
醉城夜风~8 小时前
Java详解经典算法题:接雨水(三种实现方案+原理剖析)
java·开发语言·算法