我有一个内部编写的用于发送电子邮件的电子邮件应用程序。我们已经设置了将 OAuth 2.0 与 GMail(个人和企业帐户)和 Outlook.com 帐户一起使用的选项,没有出现任何问题。
我们还可以使用用户 ID 和密码进行身份验证,但我们更喜欢 OAuth 2.0,因为我们不会以这种方式在任何地方保存密码。
我们现在收到针对 Office365 帐户执行此操作的请求。
我注意到 Office365 smtp 服务器(smtp.office365.com 端口 587)上的 hello 消息不提供 XOAUTH2 选项。
250-BY2PR0601CA0005.outlook.office365.com Hello [xx.xx.xx.xx]
250-SIZE 157286400
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH LOGIN
250-8BITMIME
250-BINARYMIME
250 CHUNKING
但是,outlook.com 的 SMTP 服务器可以:
250-BLU436-SMTP14.smtp.hotmail.com Hello [xx.xx.xx.xx]
250-TURN
250-SIZE 41943040
250-ETRN
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-8bitmime
250-BINARYMIME
250-CHUNKING
250-VRFY
250-AUTH LOGIN PLAIN XOAUTH2
250 OK
Office365可以做到这一点吗?如果没有,我们可以将Office365用户指向outlook.com smtp服务器(smtp-mail.outlook.com)还是它们完全不同?
如果可能的话,我们宁愿不使用仅用于发送电子邮件的 API,因为每个提供商的 RESTful API 当然会有很大不同。
使用 Office365 帐户发送电子邮件时使用 OAuth 2.0 的原因是我们不想在我们的服务器上存储密码。此外,如果用户更改密码,我们不会知道,除非他们告诉我们或在我们的系统端手动更新。
使用 OAuth 2.0 可以解决这个问题,并允许应用程序像其他电子邮件提供商一样流动。
我真的也想要这个功能。这将使需要发送邮件的 Office365 应用程序变得更加容易!
我做了一些搜索,发现this这似乎与我们将要得到的官方答案一样接近(答案是否定的)。
不确定我是否遗漏了什么,但这不是你想要的吗?看起来这个帖子是二月份发布的。有趣的是,这篇文章说 M365 支持 Oauth,但 Outlook.com 用户不支持。
我使用 javax.Mail 和 OAuth 作为桌面应用程序制作了一个示例。它打开登录屏幕以获取 accessToken。我遵循了多个说明,因此 JavaMail 中可能有太多权限和道具,但我成功发送了邮件。
使用 OAuth2 的 PHP 示例。
[在 GitHub 上] (https://github.com/larsonnn/php_smtp_xoauth2_microsoft.php)
<?php
/* composer.json
"require": {
"phpmailer/phpmailer": "^6.6",
"league/oauth2-client": "^2.6",
"thenetworg/oauth2-azure": "^2.1"
}
*/
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\OAuth;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\PHPMailer;
use TheNetworg\OAuth2\Client\Provider\Azure;
require "vendor/autoload.php";
$mail = new PHPMailer(true);
$provider = new Azure([
'clientId' => '',
'clientSecret' => '',
"scopes" => ["https://outlook.office.com/SMTP.Send"],
"tenant" => "",
"defaultEndPointVersion" => Azure::ENDPOINT_VERSION_2_0,
]);
$mail->setOAuth(
new OAuth(
[
'provider' => $provider,
'clientId' => '',
'clientSecret' => '',
'refreshToken' => '',
'userName' => 'mymail@office_365_email.tld',
]
)
);
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->isSMTP();
$mail->Host = 'smtp.office365.com';
$mail->Port = 587;
$mail->SMTPAuth = true;
$mail->AuthType = 'XOAUTH2';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->CharSet = PHPMailer::CHARSET_UTF8;
//Recipients
$mail->setFrom('mymail@office_365_email.tld', 'name');
$mail->addAddress('[email protected]', 'Spam');
//Content
$mail->Subject = 'Here is the subject';
$mail->Body = 'Hallo';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
我有同样的问题,我的脚本不起作用,有找到解决方案吗?
<?php
namespace App\Clases;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use DB, URL;
use GuzzleHttp\Client;
class EnviarEmail
{
//Funcion para enviar el email
public function enviar($emailEnviado = [], $asunto = '', $msg = '', $adjunto = '', $emailArea = '', $enviarCopia = '', $enviarPiePagina = '', $multiplesAdjuntos = [])
{
$clientId = ' ';
$clientSecret = ' ';
$tokenValue = ' ';
//Datos de acceso al servidor
$emailconfiguracion = DB::table('emailconfiguracion')->where('emaconid', 1)->first();
$usuario = $emailconfiguracion->emaconemail;
$password = $emailconfiguracion->emaconclave;
$host = $emailconfiguracion->emaconhost;
try {
//dd($this->getAccessToken($clientId, $clientSecret,$tokenValue));
/*
$mail->SMTPDebug = 0;
$mail->isSMTP();
$mail->charSet = "UTF-8";
$mail->Host = $host;
$mail->SMTPAuth = true;
$mail->Username = $usuario;
$mail->Password = $password;
$mail->SMTPSecure = 'STARTTLS';
$mail->Port = 587;*/
//dd($this->getAccessToken($clientId, $clientSecret,$tokenValue));
$mail = new PHPMailer(true);
$mail->SMTPDebug = 4;
$mail->isSMTP();
$mail->SMTPSecure = 'tls';
$mail->SMTPAutoTLS = true;
$mail->SMTPAuth = true;
$mail->Host = 'smtp.office365.com';
$mail->AuthType = 'XOAUTH2';
$mail->oauthUserEmail = 'my_mail';
$mail->oauthClientId = $clientId;
$mail->oauthClientSecret = $clientSecret;
$mail->oauthRefreshToken = $this->getAccessToken($clientId, $clientSecret,$tokenValue);
$mail->Port = 587;
$mail->setFrom($usuario,utf8_decode('Sistema de mejora de servicios'));
foreach ($emailEnviado as $email) {
$mail->addAddress($email);
}
if($enviarCopia == 1){//copia de la oculta
$mail->addBCC($emailArea);
}
if(count($multiplesAdjuntos) > 0){
$i = 0;
foreach ($multiplesAdjuntos as $rutas_archivo) {
$mail->addAttachment($rutas_archivo);
$i ++;
}
}
if($adjunto !== '') {
$mail->addAttachment($adjunto);
}
$piePagina = '';
if($enviarPiePagina == 1){
$piePagina = $this->consultarPiePagina();
}
$mail->isHTML(true);
$mail->Subject = utf8_decode($asunto);
$mail->Body = utf8_decode($this->htmlEmail($msg, $piePagina));
$mail->AltBody = $msg;
$mail->send();
$mail->ClearAttachments();
$mail->ClearAllRecipients();
return 'se ha enviado notificación al E-mail '.implode(",", $emailEnviado);
}catch (Exception $e) {
return "No se puedo enviar el E-mail. Error: ".$mail->ErrorInfo;
}
}
//Funcion para generar el html del E-mail
function htmlEmail($body,$piePagina) {
$url = URL::to('/').'/images/banner-email.png';
$msj = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>';
$msj .='<div style="border:1px solid #e4e4e4;border-radius:5px; width: 98%;">';
//$msj .='<div style="background-color:#B92800; text-align: center; font-weight:bold; color: #fdfdfd;"> Mensaje enviado de pruebas por favor ignórelo.</div>';
$msj .='<img src="'.$url.'" alt="baner_correo" />';
$msj .='<div style="background-color:#efefef;color: #00aeed;font-weight: bold;text-align: center; font-weight:bold;"> Notificación del Sistema de Mejora del Servicios</div>';
$msj .='<div style="margin-top:5px; padding:8px; text-align:justify;">';
$msj .= $body;
$msj .='</div>
<div style="margin-top:5px; font-size:11px; padding:8px; color:#8c8c8c; text-align:justify;">'.$piePagina.'
</div>
</div>
</html>';
return $msj;
}
//Consular la iformacion del pie de pagina
function consultarPiePagina(){
$informacionEmail = DB::table('informacionemailnotificacion')
->select('inemnocontenido')
->where('inemnoid', 1)->first();
return $informacionEmail->inemnocontenido;
}
function getAccessToken($clientId, $clientSecret, $tokenValue)
{
//$tokenEndPoint1 = 'https://login.microsoftonline.com/'.$tokenValue.'/oauth2/v2.0/token';
$client = new Client();
$tokenEndpoint = 'https://login.microsoftonline.com/c01d9bb4-6aa3-4054-9917-7a7e66d52a14/oauth2/v2.0/token';
try {
$response = $client->post($tokenEndpoint, [
'form_params' => [
'grant_type' => 'client_credentials',
'client_id' => $clientId,
'client_secret' => $clientSecret,
'scope' => 'https://outlook.office365.com/.default',
],
]);
$data = json_decode($response->getBody(), true);
return $data['access_token'];
}catch (ClientException $e) {
$response = $e->getResponse();
$errorData = json_decode($response->getBody(), true);
//return response()->json(['error' => true, 'message' => 'Error en la solicitud: '.$errorData['error_description']]);
echo 'Error en la solicitud: ' . $errorData['error_description'];
return null;
} catch (\Exception $e) {
//return response()->json(['error' => true, 'message' => 'Error inesperado: '.$e->getMessage()]);
echo 'Error inesperado: ' . $e->getMessage();
return null;
}
}
}