[AWS] SES SMTP 메일 발송하기 PHP Mailer > AWS.클라우드
AWS.클라우드

[AWS] SES SMTP 메일 발송하기 PHP Mailer

조회 154회 댓글 0건

SMTP를 이용한 메일은 PHP mail 함수를 통해 발송 시키는 가장 일반적인 방식 입니다.

여기선 AWS SDK가 아니라 STMP 설정을 통해서 메일을 발송 시키는데 PHP에서 가장 잘 만들어진 PHPMailer 라이브러리를 이용 합니다.



● AWS SMTP 서버 활용 메일 발송 - 파일 첨부와 한글 사용


 1) SMTP 설정 -> SMTP 보안 인증 생성 -> user와 password를 생성 


 2) 구성 -> 자격증명 -> 도메인 인증 , 메일인증 

    프로덕션 모드 이전일때는 보내고 받는 메일 모두 인증 해야 한다. 

    

 3) 한글 사용을 위해선 헤더 부분을 변경해 줘야 한다. 



  # composer require phpmailer/phpmailer

  //Import PHPMailer classes into the global namespace
  //These must be at the top of your script, not inside a function
  use PHPMailer\PHPMailer\PHPMailer;
  use PHPMailer\PHPMailer\SMTP;
  use PHPMailer\PHPMailer\Exception;

  //Load Composer's autoloader
  require 'vendor/autoload.php';

  //Create an instance; passing `true` enables exceptions
  $mail = new PHPMailer(true);

  # AWS SMTP 서버 활용 메일 발송 - 파일 첨부와 한글 사용
  # 1) SMTP 설정 -> SMTP 보안 인증 생성 -> user와 password를 생성
  # 2) 구성 -> 자격증명 -> 도메인 인증 , 메일인증
  #    프로덕션 모드 이전일때는 보내고 받는 메일 모두 인증 해야 한다.
  # 3) 한글 사용을 위해선 헤더 부분을 변경해 줘야 한다.
  try {
      //Server settings
      $mail->SMTPDebug = SMTP::DEBUG_SERVER;            
      $mail->isSMTP();                                  
     
      # 파일 전송 테스트일때는 오류발생 하기 전에는 0으로 하는것이 좋다.
      $mail->SMTPDebug  = 2;    // 실사용에선 0 으로 변경
      $mail->Host       = 'aws smtp 주소';              
      $mail->SMTPAuth   = true;                          
      $mail->Username   = 'aws user';                    
      $mail->Password   = 'aws password';                

      // 포트가 587 이면  
      $mail->Port       = 587;
      if ( $mail->Port == 587 ) {
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
      } else if ( $mail->Port == 465 ) {
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
      }    
     
      //Recipients
      $mail->setFrom('test@test1.com', '테스트1');
      $mail->addAddress('test@test2.com', '테스트2');     //Add a recipient
      // $mail->addAddress('ellen@example.com');               //Name is optional
      // $mail->addReplyTo('info@example.com', 'Information');
      // $mail->addCC('cc@example.com');
      // $mail->addBCC('bcc@example.com');


$mail->addReplyTo('replay@test.com');

$mail->Sender = 'noreplay@test.com'; // Return-Path 변경

      # 파일 첨부 테스트 결과 잘 된다.
      // $mail->addAttachment('/var/tmp/file.tar.gz');         //Add attachments
      // $mail->addAttachment('/tmp/image.jpg', 'new.jpg');    //Optional name

      # 샘플에서 추가 된것 - 한글 사용을 위한것
      $mail->XMailer    = "Mailer 2023.02.12";
      $mail->CharSet    = "utf-8";
      $mail->Encoding   = "base64";
      $mail->ContentType= "text/html";

      //Content
      $mail->isHTML(true);                                  //Set email format to HTML
      $mail->Subject = '한글 제목';
      $mail->Body    = '한글 HTML 바디 <b>in 한글 bold!</b>';
      // $mail->AltBody = 'non-HTML mail clients';

      $mail->send();
      echo 'Message has been sent';
  } catch (Exception $e) {
      echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
  }
 


위를 클래스로 만든 것입니다. 큰 차이는 없고 분리된것 뿐 입니다.



  use PHPMailer\PHPMailer\PHPMailer;
  use PHPMailer\PHPMailer\SMTP;
  use PHPMailer\PHPMailer\Exception;

  require 'vendor/autoload.php';

  class Mailer {
    private $mail;

    public function __construct() {
      $this->mail = new PHPMailer(true);
      $this->setup();
    }

    private function setup() {
      try {
        $this->mail->isSMTP();
        $this->mail->SMTPDebug = 2; // 실제 사용시에는 0으로 설정
        $this->mail->Host = 'aws smtp 주소';
        $this->mail->SMTPAuth = true;
        $this->mail->Username = 'aws user';
        $this->mail->Password = 'aws password';
        $this->mail->Port = 587;
        $this->mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;

        $this->mail->CharSet = 'UTF-8';
        $this->mail->Encoding = 'base64';
        $this->mail->ContentType = 'text/html';
        $this->mail->XMailer = 'Mailer 2023.02.12';
      } catch (Exception $e) {
        echo "Mailer Error: " . $this->mail->ErrorInfo;
      }
    }

    public function sendMail($from, $fromName, $to, $toName, $subject, $body, $attachments = []) {
      try {
        $this->mail->setFrom($from, $fromName);
        $this->mail->addAddress($to, $toName);

        foreach ($attachments as $attachment) {
          $this->mail->addAttachment($attachment);
        }

        $this->mail->isHTML(true);
        $this->mail->Subject = $subject;
        $this->mail->Body = $body;

        $this->mail->send();
        echo 'Message has been sent';
      } catch (Exception $e) {
        echo "Message could not be sent. Mailer Error: {$this->mail->ErrorInfo}";
      }
    }
  }
 


실행 예제 인데 DKIM 등은 여기에 빠져 있으니 필요한 경우 다른 예를 찾아야 합니다.

그리고 AWS SES에서 도메인에 dkim 설정이 되어 있으면 자동으로 생성이 됩니다.



  require 'Mailer.php'; // Mailer 클래스 파일을 포함합니다. 실제 경로에 맞게 조정하세요.

  // Mailer 클래스의 인스턴스를 생성합니다.
  $mailer = new Mailer();

  // 메일 발송 정보 설정
  $from = 'sender@example.com';  // 발신자 이메일 주소
  $fromName = '발신자 이름';      // 발신자 이름
  $to = 'recipient@example.com'; // 수신자 이메일 주소
  $toName = '수신자 이름';       // 수신자 이름
  $subject = '테스트 메일';       // 메일 제목
  $body = '<h1>메일 내용</h1><p>이것은 테스트 메일입니다.</p>'; // 메일 본문 (HTML 형식)

  // 첨부 파일 리스트 (옵션)
  $attachments = [
    '/path/to/first/file.txt',
    '/path/to/second/image.jpg'
  ];

  // 메일 발송 실행
  try {
    $mailer->sendMail($from, $fromName, $to, $toName, $subject, $body, $attachments);
    echo "메일이 성공적으로 발송되었습니다.";
  } catch (Exception $e) {
    echo "메일 발송에 실패했습니다. 에러: " . $e->getMessage();
  }
 



https://docs.aws.amazon.com/ko_kr/ses/latest/dg/send-email-concepts-email-format.html

Reply-To - 회신을 전송할 이메일 주소입니다. 기본적으로 회신은 원래 발신자 이메일 주소로 전송됩니다.

Return-Path - 반송 메일 및 수신 거부를 전송해야 할 이메일 주소입니다. "Return-Path"는 때때로 "envelope from", "envelope sender" 또는 "MAIL FROM"으로 불립니다.


Amazon SES를 통해 보내는 메시지는 기본적으로 amazonses.com의 서브도메인을 기본 MAIL FROM 도메인으로 자동 사용합니다. 

발신자 정책 프레임워크(SPF) 인증은 기본 MAIL FROM 도메인이 이메일을 보낸 애플리케이션과 일치하기 때문에 이러한 메시지를 성공적으로 검증합니다. 이 경우 SES입니다.


SES 기본 MAIL FROM 도메인을 사용하고 싶지 않고, 

소유한 도메인의 서브도메인을 사용하고 싶다면, 이는 SES에서 사용자 정의 MAIL FROM 도메인 사용으로 지칭됩니다. 

이를 위해서는 사용자 정의 MAIL FROM 도메인에 대한 자체 SPF 레코드를 게시해야 합니다. 

또한, SES는 이메일 제공업체가 보내는 반송 및 불만 통지를 도메인이 수신할 수 있도록 MX 레코드 설정도 요구합니다.


사용자 정의 MAIL FROM 도메인을 사용함으로써 SPF, DKIM 또는 둘 모두를 사용하여 도메인 기반 메시지 인증, 보고 및 준수(DMARC) 검증을 달성할 수 있는 유연성을 가질 수 있습니다. DMARC는 발신자 도메인이 도메인에서 보낸 이메일이 하나 이상의 인증 시스템으로 보호된다는 것을 나타낼 수 있게 합니다. DMARC 검증을 달성하는 두 가지 방법은 SPF를 통한 DMARC 준수와 DKIM을 통한 DMARC 준수입니다.


7170d21e718d79752aca7656557c7980_1710075442_5982.png
 


사용자 정의 MAIL FROM 도메인 선택(MAIL FROM 이란 메일도메인을 말함)

다음에서 MAIL FROM 도메인이라는 용어는 항상 소유한 도메인의 서브도메인을 의미합니다. 

사용자 정의 MAIL FROM 도메인으로 사용하는 이 서브도메인은 다른 용도로 사용되지 않아야 하며 다음 요구 사항을 충족해야 합니다:

  - MAIL FROM 도메인은 검증된 신원(이메일 주소 또는 도메인)의 부모 도메인의 서브도메인이어야 합니다.

  - MAIL FROM 도메인은 이메일을 보내는 데 사용하는 서브도메인이어서는 안 됩니다.

  - MAIL FROM 도메인은 이메일을 수신하는 데 사용하는 서브도메인이어서는 안 됩니다.


Return-Path가 AWS SES의 기본 주소로 설정되는 것은 AWS SES의 배달 관리 메커니즘의 일부입니다. 
이메일 반송을 효과적으로 관리하고자 한다면, AWS SES의 반송 메시지 처리 기능을 활용하거나, Custom MAIL FROM 설정을 통해 관련 설정을 조정하는 것이 좋습니다. 
(MAIL FROM 앞쪽 계정(MessageId)에 해당하는 부분까지 변경하는것 안되어 반송에 대한 문제가 있습니다.)

DMARC를 준수하려면 헤더 From의 도메인과 MAIL FROM 도메인이 일치해야 합니다.

* 참고 할것

  - AWS SES 도메인 확인된 자격 증명 인증 방법(BIND 네임서버) > AWS.클라우드  

  - 메일인증용 DKIM 키 만드는 방법 > 리눅스서버 

  - [mail] DKIM 키만들고 체크하는 방법 > 리눅스서버 

  - 메일 MX레코드 체크 DNS DIG 쉽게 사용하는 구글관리 도구상자 

  - PHPMailer 파일첨부 및 dkim 사용하기 > PHP 


  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
전체 61건 1 페이지
  • profile_image 페이지를 가져오지 못하니 404인가 아니면 서버쪽 설정 문제 이므로 500번때 코드가 나올까?결론은 아래 처럼 502 오류가 발생 합니다.ELB에서 리스너가 없을 경우 서버로 접속해서 데이터를 가져오지 못하는 상황에선 아래와 같은 메시지를 만나게 됩니다.포트지정 설정을 잘못해도 동일 하겠지요. 학술적으로 정리를 해보면 아래와 같이 말을 할 수 있다. HTTP 502 코드는 "Bad Gateway" 오류로 웹 서버가 게이트웨이나 프록시 서버를 통…
  • profile_image https용도로 사용할 수 있는 AWS Cerificate Manager 페이지에서의 인증서 생성하는 것에 대한 것입니다.이곳에선 외부에서 받은 인증서 파일을 올리거나 무료로 인증서를 생성 할 수 있습니다.AWS 무료인증서는 속도가 빠른 장점이 있고 무료이지만 문제는 이것을 다른곳에선 사용하지 못한 다는것입니다.예를 들면 EC2의 웹서버에서 https 용도로 사용하지 못합니다.그럼 EC2에선 외부에서 생성한 인증서를 가져와 사용하던가. 아니면 …
  • profile_image 클라우드 와치 수동으로 내보내기 하려 하는데 아래와 같은 메시지를 보게 되면GetBucketAcl call on the given bucket failed. Please check if CloudWatch Logs has been granted permission to perform this operation."S3 버킷에 대한 GetBucketAcl 호출 실패" 오류는 CloudWatch Logs가 지정된 S3 버킷에 대한 접근 권한이 없음을…
  • profile_image 온프레미스 환경에선 주기적으로 압축하여 보관하거나 복사하거나 해서 관리 후 삭제 하기도 하는데. 오토스케일링 사용으로 EC2가 없어지는 경우 이런 방식이 필요하다. 물론 EFS를 사용하는 방법도 있겠지만 난 그러고 싶지 않다. ● 클라우드와치 Agent를 설치 한다.yum -y install amazon-cloudwatch-agent▷ 아래는 테스트 하기 위한 로그를 2초에 한번 씩 발생 시킨다.while true; do (curl http:/…
  • profile_image NAT(Network Address Translation) 게이트웨이 구성으로 VPC(Virtual Private Cloud) 환경에서 프라이빗 서브넷에 있는 인스턴스들이 인터넷이나 AWS의 다른 공개 서비스에 접근할 수 있게 된다. ● NAT 게이트웨이NAT 게이트웨이는 AWS에서 관리하는 서비스로, 높은 가용성과 자동 확장 기능을 제공합니다. NAT 게이트웨이를 사용하면 별도의 관리 없이도 프라이빗 서브넷의 인스턴스가 인터넷에 접근할 수 있…
  • profile_image 아마존리눅스2에서 기본적으로 mysql 클라이언트가 없어서 접속을 하지 못하는 문제가 있어서 설치 하는 도중에 발생한 문제를 다음에는 쉽게 해결하기 위해서 적습니다.이게 없으면 덤프받은것 올리지도 못하고 해당 서버에서 디비서버로 접속도 못하네요~● mysql 클라이언트 설치 시도amazon-linux-extras install epel -ywget https://dev.mysql.com/get/mysql80-community-release-el…
  • profile_image S3에서 올린 본인 이외에 제 3자도 읽을 수 있도록 올린 것이 아닌 경우 클라우드 프론트에서만 읽을 수 있는 권한을 주는 방법에 대한 것이다. 프로그램으로 하나 씩 올리면서 권한을 줬으면 문제 되지 않는다.그렇지 않고. 아래 처럼 올린 경우 권한이 없어서 오류가 발생 한다. s3cmd sync /로컬/디렉토리 s3://버킷이름 아래처럼 배포를 생성할때 설정 해도 되고 다 설정한 다음 후에 수정을 해도 됩니다.<Error><Co…