如何在 PHPMailer for Exchange Online 中实现 Oauth 2.0

问题描述 投票:0回答:1

正如你们许多人所知,Microsoft 从 2022 年 1 月 10 日起将弃用 Exchange online 的基本身份验证(登录名和密码)。您可以在这里阅读全文:

https://www.microsoft.com/en-us/microsoft-365/blog/2022/09/01/microsoft-retires-basic-authentication-in-exchange-online/#:~:text=As% 20先前%20宣布%2C%20we%20是,用户%20移动%20至%20现代%20身份验证

我目前正在使用 PHPMailer 从应用程序通过 SMTP 发送电子邮件。

当前代码的工作示例:

<?php
    include "vendor/autoload.php";
    
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\Exception;

    $mail = new PHPMailer;
    $mail->IsSMTP();
    $mail->Host = "smtp.office365.com";
    $mail->Port = "587";
    $mail->SMTPAuth = true;
    $mail->Username = "[email protected]";
    $mail->Password = "my_password";
    $mail->SMTPSecure = "tls";
    $mail->From = "[email protected]";
    $mail->FromName = "my_name";
    $mail->AddAddress("[email protected]");
    $mail->IsHTML(true);
    $mail->Subject = "This is a test subject";
    $mail->Body = "Hello, how are you?";
    $mail->Send();
?>

我想从基本身份验证转移到 OAuth 2.0。在阅读了大量文档、在网上搜索了 3 天、尝试了又尝试之后,我无法让它工作。

我的新代码示例:

<?php
    include "vendor/autoload.php";

    use PHPMailer\PHPMailer\Exception;
    use PHPMailer\PHPMailer\OAuth;
    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use Stevenmaguire\OAuth2\Client\Provider\Microsoft;
    
    $mail = new PHPMailer;
    $mail->isSMTP();
    $mail->Host = "smtp.office365.com";
    $mail->SMTPAuth = true;
    $mail->AuthType = "XOAUTH2";
    $mail->SMTPDebug = SMTP::DEBUG_LOWLEVEL;
    $mail->SMTPSecure = "tls";
    $mail->Port = 587;

    $username = "[email protected]";
    $clientId = "client_id_from_azure_app_registration";
    $clientSecret = "client_secret_from_azure_app_registration";
    $redirectURI = "my_redirect_uri";
    $Token = "my_token";
    $mail->refresh_token = $Token;

    $provider = new Stevenmaguire\OAuth2\Client\Provider\Microsoft(
        [
            "clientId" => $clientId,
            "clientSecret" => $clientSecret,
            "redirectUri" => $redirectURI
        ]
    );

    $provider->urlAPI = "https://outlook.office365.com/.default";
    $provider->scope = "Mail.Send";

    $mail->setOAuth(
        new OAuth(
            [
                "provider" => $provider,
                "clientId" => $clientId,
                "clientSecret" => $clientSecret,
                "refreshToken" => $Token, 
                "userName" =>$username
            ]
        )
    );

    $mail->From = $username;
    $mail->AddAddress("[email protected]");   
    $mail->IsHTML(true);
    $mail->Subject = "This is a test subject";
    $mail->Body = "Hello, how are you?";
    $mail->Send();
?>

我通过 Postman 生成访问令牌并在上面的代码中使用此令牌:

Postman screen shot

应用程序在 Microsoft Azure 中配置为具有所需的权限:

Azure config

这是我得到的输出:

2022-09-27 13:51:38 Connection: opening to smtp.office365.com:587, timeout=300, options=array()
2022-09-27 13:51:38 Connection: opened
2022-09-27 13:51:38 SMTP INBOUND: "220 AS4P191CA0011.outlook.office365.com Microsoft ESMTP MAIL Service ready at Tue, 27 Sep 2022 13:51:37 +0000"
2022-09-27 13:51:38 SERVER -> CLIENT: 220 AS4P191CA0011.outlook.office365.com Microsoft ESMTP MAIL Service ready at Tue, 27 Sep 2022 13:51:37 +0000
2022-09-27 13:51:38 CLIENT -> SERVER: EHLO
2022-09-27 13:51:38 SMTP INBOUND: "250-AS4P191CA0011.outlook.office365.com Hello [2a02:4780:8:2::25]"
2022-09-27 13:51:38 SMTP INBOUND: "250-SIZE 157286400"
2022-09-27 13:51:38 SMTP INBOUND: "250-PIPELINING"
2022-09-27 13:51:38 SMTP INBOUND: "250-DSN"
2022-09-27 13:51:38 SMTP INBOUND: "250-ENHANCEDSTATUSCODES"
2022-09-27 13:51:38 SMTP INBOUND: "250-STARTTLS"
2022-09-27 13:51:38 SMTP INBOUND: "250-8BITMIME"
2022-09-27 13:51:38 SMTP INBOUND: "250-BINARYMIME"
2022-09-27 13:51:38 SMTP INBOUND: "250-CHUNKING"
2022-09-27 13:51:38 SMTP INBOUND: "250 SMTPUTF8"
2022-09-27 13:51:38 SERVER -> CLIENT: 250-AS4P191CA0011.outlook.office365.com Hello [2a02:4780:8:2::25]250-SIZE 157286400250-PIPELINING250-DSN250-ENHANCEDSTATUSCODES250-STARTTLS250-8BITMIME250-BINARYMIME250-CHUNKING250 SMTPUTF8
2022-09-27 13:51:38 CLIENT -> SERVER: STARTTLS
2022-09-27 13:51:38 SMTP INBOUND: "220 2.0.0 SMTP server ready"
2022-09-27 13:51:38 SERVER -> CLIENT: 220 2.0.0 SMTP server ready
2022-09-27 13:51:38 CLIENT -> SERVER: EHLO
2022-09-27 13:51:38 SMTP INBOUND: "250-AS4P191CA0011.outlook.office365.com Hello [2a02:4780:8:2::25]"
2022-09-27 13:51:38 SMTP INBOUND: "250-SIZE 157286400"
2022-09-27 13:51:38 SMTP INBOUND: "250-PIPELINING"
2022-09-27 13:51:38 SMTP INBOUND: "250-DSN"
2022-09-27 13:51:38 SMTP INBOUND: "250-ENHANCEDSTATUSCODES"
2022-09-27 13:51:38 SMTP INBOUND: "250-AUTH LOGIN XOAUTH2"
2022-09-27 13:51:38 SMTP INBOUND: "250-8BITMIME"
2022-09-27 13:51:38 SMTP INBOUND: "250-BINARYMIME"
2022-09-27 13:51:38 SMTP INBOUND: "250-CHUNKING"
2022-09-27 13:51:38 SMTP INBOUND: "250 SMTPUTF8"
2022-09-27 13:51:38 SERVER -> CLIENT: 250-AS4P191CA0011.outlook.office365.com Hello [2a02:4780:8:2::25]250-SIZE 157286400250-PIPELINING250-DSN250-ENHANCEDSTATUSCODES250-AUTH LOGIN XOAUTH2250-8BITMIME250-BINARYMIME250-CHUNKING250 SMTPUTF8
2022-09-27 13:51:38 Auth method requested: XOAUTH2
2022-09-27 13:51:38 Auth methods available on the server: LOGIN,XOAUTH2

Fatal error: Uncaught League\OAuth2\Client\Provider\Exception\IdentityProviderException: Bad Request in /home/u760208683/vendor/stevenmaguire/oauth2-microsoft/src/Provider/Microsoft.php:79 Stack trace: #0 /home/u760208683/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(628): Stevenmaguire\OAuth2\Client\Provider\Microsoft->checkResponse(Object(GuzzleHttp\Psr7\Response), Array) #1 /home/u760208683/vendor/league/oauth2-client/src/Provider/AbstractProvider.php(537): League\OAuth2\Client\Provider\AbstractProvider->getParsedResponse(Object(GuzzleHttp\Psr7\Request)) #2 /home/u760208683/vendor/phpmailer/phpmailer/src/OAuth.php(115): League\OAuth2\Client\Provider\AbstractProvider->getAccessToken(Object(League\OAuth2\Client\Grant\RefreshToken), Array) #3 /home/u760208683/vendor/phpmailer/phpmailer/src/OAuth.php(128): PHPMailer\PHPMailer\OAuth->getToken() #4 /home/u760208683/vendor/phpmailer/phpmailer/src/SMTP.php(598): PHPMailer\PHPMailer\OAuth->getOauth64() #5 /home/u760208683/vendor/phpmailer/phpmailer/src/PHPMailer in /home/u760208683/vendor/stevenmaguire/oauth2-microsoft/src/Provider/Microsoft.php on line 79

有人能指出我正确的方向吗?

提前非常感谢!

亲切的问候, 劳伦斯

php azure authentication oauth-2.0 phpmailer
1个回答
0
投票
Fatal error: Uncaught League\OAuth2\Client\Provider\Exception\IdentityProviderException:

此错误是由于您提供了 access_token 来发送邮件而不是刷新_token。

首先,添加范围offline_access以在授权网址中获取refresh_token并将其保存在应用程序中的某个位置(过期时间为24小时或90天,具体取决于应用程序类型) 一旦您拥有刷新令牌,您就可以使用相同的令牌发送任意数量的邮件。

您可以通过在网址中提供另一个未过期的刷新令牌并将 grant_type 更改为刷新令牌并添加密钥刷新令牌来获取新令牌。

© www.soinside.com 2019 - 2024. All rights reserved.