如何在不发送电子邮件和PHP中不使用pear的情况下检查SMTP身份验证。他们可以用主机,端口,用户名和密码检查身份验证吗?
我检查了swiftmailer,它说认证是在发送电子邮件。 http://swiftmailer.org/docs/sending.html#smtp-with-a-username-and-password
同样在phpmailer上。 https://github.com/PHPMailer/PHPMailer/blob/master/examples/smtp.phps
答案 0 :(得分:2)
不可否认,这不是最干净的解决方案,但它会起作用。下面复制的是expect
脚本,它将连接到SMTP服务器,尝试进行身份验证,然后退出会话并断开连接。如果expect
脚本的最后一行输出为235 2.7.0 Authentication successful
(或响应代码以2xx开头的其他类似响应),则使用提供的凭据进行身份验证成功,否则身份验证失败。您可以使用expect
从PHP脚本调用此shell_exec()
脚本,并解析输出以测试是否可以使用给定一组凭据的SMTP服务器进行身份验证。
#!/usr/bin/expect
set mailserver "smtp.smtpserver.com"; #fqdn of SMTP server
set credentials "AG1xxxxxxxxxxxxxxxxxxxDNy"; #this string should be "\0username\0password" base64-encoded.
spawn telnet $mailserver 25
expect "failed" {
send_user "$mailserver: connect failed\n"
exit
} "2?? *" {
} "4?? *" {
exit
} "refused" {
send_user "$mailserver: connect refused\n"
exit
} "closed" {
send_user "$mailserver: connect closed\n"
exit
} timeout {
send_user "$mailserver: connect to port 25 timeout\n"
exit
}
send "HELO foo.com\r"
expect "2?? *" {
} "5?? *" {
exit
} "4?? *" {
exit
}
send "AUTH PLAIN $credentials\r";
expect "2?? *" {
} "5?? *" {
exit
} "4?? *" {
exit
}
send "QUIT\r"
exit
答案 1 :(得分:0)
使用PHPmailer可以测试连接而无需发送电子邮件。
我添加了该类的函数otuside(但是可以在控制器中使用它而不会出现问题)
/*
|--------------------------------------------------------------------------
| USE in file
|--------------------------------------------------------------------------
|
| Need add "use" this because:
| - PHPMailer\PHPMailer\Exception -> catch exceptions of PHPmailer
| - PHPMailer\PHPMailer\SMTP -> Do the conexión of smtp server
|
*/
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
/**
* Test connection SMTP
* @param String $route Host route
* @param Integer $port Port to connect
* @param String $userName Email or user name
* @param String $userPass Password from user
* @param String $from Mail from
* @param String $to Mail to
* @return Array ['status'=>boolean,'logs'=>array]
*/
function testSMTP($route,$port,$userName = null,$userPass = null,$from=null,$to=null){
//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
date_default_timezone_set('Etc/UTC');
$logs = [];
$status_ok = false;
//Create a new SMTP instance
$logs = NewLog($logs,"Starting SMTP test");
$smtp = new SMTP();
//Enable to show all logs while load page
//$smtp->do_debug = SMTP::DEBUG_CONNECTION;
try {
//Connect to an SMTP server
$logs = NewLog($logs,"Testing SMTP connection");
if (!$smtp->connect($route, $port)) {
throw new Exception('Connect failed');
}
//Say hello
if (!$smtp->hello(gethostname())) {
throw new Exception('EHLO failed: ' . $smtp->getError()['error']);
}
$logs = NewLog($logs,"SMTP connected");
//Get the list of ESMTP services the server offers
$e = $smtp->getServerExtList();
//If server can do TLS encryption, use it
if (is_array($e) && array_key_exists('STARTTLS', $e)) {
$tlsok = $smtp->startTLS();
if (!$tlsok) {
throw new Exception('Failed to start encryption: ' . $smtp->getError()['error']);
}
//Repeat EHLO after STARTTLS
if (!$smtp->hello(gethostname())) {
throw new Exception('EHLO (2) failed: ' . $smtp->getError()['error']);
}
//Get new capabilities list, which will usually now include AUTH if it didn't before
$e = $smtp->getServerExtList();
}
//If server supports authentication, do it (even if no encryption)
if(!empty($userName) && !empty($userPass)){
if (is_array($e) && array_key_exists('AUTH', $e)) {
if ($smtp->authenticate($userName, $userPass)) {
$logs = NewLog($logs,"SMTP user loged");
} else {
throw new Exception('Authentication failed: ' . $smtp->getError()['error']);
}
}
}
//checkeamos el RCPT TO y MAIL FROM con los metodos de
if (!empty($to) && !empty($from)) {
$logs = NewLog($logs,"Testing SMTP send email");
if(!$smtp->mail($from)){
throw new Exception('MAIL FROM: ' . $smtp->getError()['error']);
}
if(!$smtp->recipient($to)){
throw new Exception('RCPT TO: ' . $smtp->getError()['error']);
}
$logs = NewLog($logs,"Test SMTP send it's ok");
}
$logs = NewLog($logs,"End SMTP test - OK");
$status_ok = true;
} catch (Exception $e) {
$logs = NewLog($logs,'SMTP error: ' . $e->getMessage(), "\n");
}
//Whatever happened, close the connection.
$smtp->quit();
//return result
return [
'logs' => $logs,
'status' => $status_ok
];
}
function NewLog ($listLogs,$log){
$listLogs[] = "[".date('Y.m.d H:i:s')."] ".$log;
return $listLogs;
}
您可以在控制器旁边使用此功能,但最好在类中使用它。