[求助]請問PHP mail認證問題?

Home Home
引用 | 編輯 chris710908
2005-05-27 20:18
樓主
推文 x0
請問各位~~
          我想透過自己用了MAIL SERVER 發信~~但是位了部讓有心
人士透過我的SERVER發信~我想採用SMTP認證方式,我環境是php+mysql
請問有什麼辦法可以讓php server有SMTP認證功能,或者寫網頁的時候
可以透過哪些語法來達成SMTP認證?請教了~~謝謝

獻花 x0
引用 | 編輯 xxxzzz
2005-05-28 00:09
1樓
  
利用fsockopen函式即可
fsockopen函式用法請參考
http://www.php5.idv.tw/modules.php?mod=books&act=show&shid=492

獻花 x0
引用 | 編輯 chris710908
2005-05-28 00:56
2樓
  
感謝大大~~可是以上的語法是開啟SMTP的~
但是關於認證帳號跟密碼的部份好像不能設
因為我想透過認證帳號密碼的方式發MAIL
請問要如何做?

獻花 x0
引用 | 編輯 xxxzzz
2005-05-28 01:19
3樓
  
下面是引用chris710908於2005-05-28 00:56發表的 :
感謝大大~~可是以上的語法是開啟SMTP的~
但是關於認證帳號跟密碼的部份好像不能設
因為我想透過認證帳號密碼的方式發MAIL
請問要如何做?
剛好有範例
如下..
http://www.knowsky.com/list.asp?id=17308

獻花 x0
引用 | 編輯 chris710908
2005-05-28 01:52
4樓
  
表情好像可以耶~~大大真是厲害~小弟在問個問題
因為老師希望可以有那種群發MAIL的功能,就是說不用每次只寄一封
像利用echo send_mail('EMIAL位址','hello','OK');
這樣要怎樣才能將資料庫的欄位讀出來然後寄發MAIL?(資料庫中已有MAIL資料欄位)

獻花 x0
引用 | 編輯 xxxzzz
2005-05-28 11:40
5樓
  
下面是引用chris710908於2005-05-28 01:52發表的 :
表情好像可以耶~~大大真是厲害~小弟在問個問題
因為老師希望可以有那種群發MAIL的功能,就是說不用每次只寄一封
像利用echo send_mail('EMIAL位址','hello','OK');
這樣要怎樣才能將資料庫的欄位讀出來然後寄發MAIL?(資料庫中已有MAIL資料欄位)

假設您已會從資料庫讀出資料處理

假設有一堆要寄的Email位址,形式如下(用逗號,分隔)
aa@aa.aa,bb@123.123,cc@abc.abc

我改上面的程式示範
改成
echo send_mail('aa@aa.aa,bb@123.123,cc@abc.abc','發信標題','發信內容');

再來修改下面這一行
$smtp[] = array("RCPT TO: <".$to.">".$lb,"250","RCPT TO error: ");

改成
$to_arr=split(",",$to);
$to_arr_num=count($to_arr);
for($i = 0 ; $i < $to_arr_num ; $i++){
  $smtp[] = array("RCPT TO: <".$to_arr[$i].">".$lb,"250","RCPT TO error: ");
}
即可

獻花 x0
引用 | 編輯 chris710908
2005-05-28 13:42
6樓
  
恩~~這樣子我大概了解了..因為之前我是用MXP套件PHP線上郵寄
<?php
$mailtype='Content-Type:text/html;charset=big5'
$mailFrom='chris@pchome.com.tw '
$mailTo=$row_RecMember['m_email'];
$mailCC=''
$mailBCC=''
$mailSubject='會員系統密碼認證信'
$mailContent = nl2br($row_RecMember['m_nick'].'您好,您的密碼為:'.$row_RecMember['m_passwd']);
$maildata = "From:$mailFrom\r\n";
if ($mailCC != '') {
$maildata .= "CC:$mailCC\r\n";
}
if ($mailBCC != '') {
$maildata .= "BCC:$mailBCC\r\n";
}
$maildata .= "$mailtype";
mail($mailTo,$mailSubject,$mailContent,$maildata);
?>

那我是藉由前一頁所傳過來的SESSION(輸入的EMAIL)然後檢查資料庫有沒有相關資料
(依據$row_RecMember['m_email'];)有則寄出MAI,我的目的是想說因為這函式並沒有
提供SMTP認證,所以我想整合大大所提供的根現有的函式,這樣辦的到嗎?
很謝謝大大的教學,小弟還在學習當中~ 表情 L

獻花 x0
引用 | 編輯 xxxzzz
2005-05-28 21:25
7樓
  
既然您已經有其他可用的郵寄程式
那只需將上面程式留下認證的部分
其他全部刪除
再判斷是否認證通過
通過就執行你本來的程式
修改如下
複製程式
<?
        $smtp_acc =""; //Smtp認証的用戶名
        $smtp_pass="";          //Smtp認証的密碼,一般等同pop3密碼
        $smtp_host="";    //SMTP伺服器位址,類似 smtp.tom.com
        $lb="\r\n";                    //linebreak

        $smtp = array(
                //2、發送Auth Login,期待返回334
                array("AUTH LOGIN".$lb,"334","AUTH error:"),
                //3、發送經過Base64編碼的用戶名,期待返回334
                array(base64_encode($smtp_acc).$lb,"334","AUTHENTIFICATION error : "),
                //4、發送經過Base64編碼的密碼,期待返回235
                array(base64_encode($smtp_pass).$lb,"235","AUTHENTIFICATION error : "));
         //打開smtp伺服器端口
        $fp = @fsockopen($smtp_host, 25);
        if (!$fp) echo "<b>Error:</b> Cannot conect to ".$smtp_host."<br>";
        while($result = @fgets($fp, 1024)){if(substr($result,3,1) == " ") { break; }}
        
        $result_str="";
        //發送smtp數組中的命令/數據
        foreach($smtp as $req){
                //發送訊息
                @fputs($fp, $req[0]);
                //如果需要接收伺服器返回訊息,則
                if($req[1]){
                        //接收訊息
                        while($result = @fgets($fp, 1024)){
                                if(substr($result,3,1) == " ") {break;}                                                
                        }
                        if (!strstr($req[1],substr($result,0,3))){
                                $result_str.=$req[2].$result."<br>";
                        }
                }
        }
        //關閉連接
        @fclose($fp);
if(!$result_str){
echo"認證成功,在這邊改成你要執行的程式";
}else{
echo "錯誤訊息<br>" . $result_str;
}
?>


獻花 x0
引用 | 編輯 chris710908
2005-05-28 23:29
8樓
  
xxxzzz大大~~我也按照你的方式,是把我上面的程式碼貼進去
if(!$result_str){
echo"認證成功,這邊改成你要執行的程式";<---是貼在這邊ㄇ?
}else{
echo "錯誤訊息<br>" . $result_str;
}
~~結果要執行PHP的時候呈現空白,是我哪裡用錯了ㄇ?

獻花 x0
引用 | 編輯 xxxzzz
2005-05-29 00:51
9樓
  
下面是引用chris710908於2005-05-28 23:29發表的 :
xxxzzz大大~~我也按照你的方式,是把我上面的程式碼貼進去
if(!$result_str){
echo"認證成功,這邊改成你要執行的程式";<---是貼在這邊ㄇ?
}else{
echo "錯誤訊息<br>" . $result_str;
}
~~結果要執行PHP的時候呈現空白,是我哪裡用錯了ㄇ?

是貼在那邊沒錯
如果只貼您上面那段程式,正確執行完當然會是空白的,
因為沒有輸出其他東西
如果您從資料庫取出來的資料無誤,那應該收的到信

剛試了一下...如下
我將要從資料庫取資料的變數刪掉以方便測試...可正確執行
if(!$result_str){
$mailtype='Content-Type:text/html;charset=big5'
$mailFrom='chris@pchome.com.tw'
$mailTo='xxx@xxx.xxx.xx'
$mailCC=''
$mailBCC=''
$mailSubject='會員系統密碼認證信'
$mailContent = nl2br('您好,您的密碼為:');
$maildata = "From:$mailFrom\r\n";
if ($mailCC != '') {
$maildata .= "CC:$mailCC\r\n";
}
if ($mailBCC != '') {
$maildata .= "BCC:$mailBCC\r\n";
}
$maildata .= "$mailtype";
mail($mailTo,$mailSubject,$mailContent,$maildata);
}else{
echo "錯誤訊息<br>" . $result_str;
}

獻花 x0
引用 | 編輯 chris710908
2005-05-29 01:43
10樓
  
以下是原始碼
<?
    $smtp_acc ="chris"; //Smtp認証的用戶名
    $smtp_pass="666";       //Smtp認証的密碼,一般等同pop3密碼
    $smtp_host="61.62.*.*";   //SMTP伺服器位址,類似 smtp.tom.com
    $lb="\r\n";             //linebreak

    $smtp = array(
          //2、發送Auth Login,期待返回334
          array("AUTH LOGIN".$lb,"334","AUTH error:"),
          //3、發送經過Base64編碼的用戶名,期待返回334
          array(base64_encode($smtp_acc).$lb,"334","AUTHENTIFICATION error : "),
          //4、發送經過Base64編碼的密碼,期待返回235
          array(base64_encode($smtp_pass).$lb,"235","AUTHENTIFICATION error : "));
      //打開smtp伺服器端口
    $fp = @fsockopen($smtp_host, 25);
    if (!$fp) echo "<b>Error:</b> Cannot conect to ".$smtp_host."<br>";
    while($result = @fgets($fp, 1024)){if(substr($result,3,1) == " ") { break; }}
   
    $result_str="";
    //發送smtp數組中的命令/數據
    foreach($smtp as $req){
          //發送訊息
          @fputs($fp, $req[0]);
          //如果需要接收伺服器返回訊息,則
          if($req[1]){
                //接收訊息
                while($result = @fgets($fp, 1024)){
                    if(substr($result,3,1) == " ") {break;}                                
                }
                if (!strstr($req[1],substr($result,0,3))){
                    $result_str.=$req[2].$result."<br>";
                }
          }
    }
    //關閉連接
    @fclose($fp);
if(!$result_str){
$mailtype='Content-Type:text/html;charset=big5'
$mailFrom='webmaster@61.62.73.210'
$mailTo=$row_RecMember['m_email'];
$mailCC=''
$mailBCC=''
$mailSubject='會員系統密碼認證信'
$mailContent = nl2br($row_RecMember['m_nick'].'您好,您的密碼為:'.$row_RecMember['m_passwd']);
$maildata = "From:$mailFrom\r\n";
if ($mailCC != '') {
$maildata .= "CC:$mailCC\r\n";
}
if ($mailBCC != '') {
$maildata .= "BCC:$mailBCC\r\n";
}
$maildata .= "$mailtype";
mail($mailTo,$mailSubject,$mailContent,$maildata);
}else{
echo "錯誤訊息<br>" . $result_str;
}
?>

執行完之後~~出現錯誤訊息
AUTH error:502 Unknown command
AUTHENTIFICATION error : 502 Unknown command
AUTHENTIFICATION error : 502 Unknown command
這樣是不是認證錯誤阿~~ㄚ我快瘋了~~寫程式好難喔~~ 表情
我的MAIL SERVER適用軟體建的~基本上沒問題,但用程式去寫好像會錯誤
這是怎嚜回事?麻煩大大了~ 表情

獻花 x0
引用 | 編輯 chris710908
2005-05-29 01:55
11樓
  
還有~~我PHP.INI中SERVER也有設好了
那網頁不採用認證的話是可以跑的~布過採認證
就不行~後面還有些程式碼~只要是當使用者輸入MAIL後
核對資料庫後如果有這MAIL~那嚜就顯示"MNAIL已寄出"
沒有則顯示"抱歉~資料庫無此資料"~不知道這會部會影響到?

獻花 x0
引用 | 編輯 xxxzzz
2005-05-29 13:37
12樓
  
我想問幾個問題
1.最初3樓的那個程式,確實可用嗎?

2.您在8樓執行PHP的時候呈現空白,信有寄出嗎?

另外我想幾個可能的原因
1.
再把刪掉的
//1、EHLO,期待返回220或者250
array("EHLO ".$loc_host.$lb,"220,250","HELO error: "),
補回去看看

2.
502 Unknown command的錯誤訊息
是否您的SMTP不支援帳號密碼認證
telnet loclalhost 25
打上
EHLO localhost
是否有AUTH LOGIN的字樣?

3.
改用其他方法認證
例如:pop3認證
複製程式
<?
function pop3_auth(){
        $pop3_acc =""; //pop3認証的用戶名
        $pop3_pass="";          //pop3認証的密碼
        $pop3_host="";    //pop3伺服器位址
       $sock = @fsockopen( $pop3_host,110);

       if( !$sock )
              return "無法開啟連線";

       $msg = fgets( $sock, 256 );
       if( !strstr( $msg, "+OK" ) ) {
              fclose( $sock );
              return "開啟連線錯誤";
       }

       fputs( $sock, "USER $pop3_acc\r\n" );

       $msg = fgets( $sock, 256 );
       if( !strstr( $msg, "+OK" ) ) {
              fclose( $sock );
              return "輸入帳號錯誤";

       }

       fputs( $sock, "PASS $pop3_pass\r\n" );

       $msg = fgets( $sock, 256 );
       if( !strstr( $msg, "+OK" ) ) {
              fclose( $sock );
              return "帳號或密碼錯誤";
       }

       fputs( $sock, "QUIT\r\n" );
       fclose( $sock );
}
if(!pop3_auth()){
//認證通過欲執行的程式
$mailtype='Content-Type:text/html;charset=big5'
$mailFrom=''
$mailTo=''
$mailCC=''
$mailBCC=''
$mailSubject='會員系統密碼認證信'
$mailContent = nl2br('您好,您的密碼為:');
$maildata = "From:$mailFrom\r\n";
if ($mailCC != '') {
$maildata .= "CC:$mailCC\r\n";
}
if ($mailBCC != '') {
$maildata .= "BCC:$mailBCC\r\n";
}
$maildata .= "$mailtype";
mail($mailTo,$mailSubject,$mailContent,$maildata);
}else{
//認證失敗欲執行的程式
echo pop3_auth();
}
?>

4.
只執行上面的程式(先不要跟你其他的部分整合),如果可執行
或是您在8樓的情形也可正確執行
則應該是您整合其他部分時產生的問題
只看這部分似乎較難找出問題所在

獻花 x0
引用 | 編輯 xxxzzz
2005-05-29 13:44
13樓
  
還有如果您的主機許可
也可以用imap_open()這個函式認證
這是最簡單的

獻花 x0
引用 | 編輯 chris710908
2005-05-29 14:21
14樓
  
1.那個程式是可用的~但只能用於無SMTP認證的方式

2.信沒有寄出,我看到MAIL SERVER的訊息是Error: [10054] Connection reset by peer
SMTP connection with 61.62.*.* ended. ID=1~我的軟體是ArGoSoft Mail Server

3.大大用的那個POP3方法,可以寄出信(無整合其他程式碼),但是這樣可以避免我的MAIL SERVER 不被RELY嗎?因為我的SERVER的enable SMTP認證沒開啟才能寄出去,開啟的話,一樣寄不出。

4.大大說的imap_open()事怎樣的方式,有什麼限制嗎,我的MAIL SERVER好像沒看到imap這個選項?

5.我的SERVER應該是可以支援SMTP認證的~因為我用類似OUTLOOKㄉ軟體寄發信~都有用SMTP認證
只是在PHP的環境下用程式既不出去~這跟PHP.INI有關係ㄇ?因為這檔案裡面不支援認證

獻花 x0
引用 | 編輯 xxxzzz
2005-05-29 17:53
15樓
  
下面是引用chris710908於2005-05-29 14:21發表的 :
3.大大用的那個POP3方法,可以寄出信(無整合其他程式碼),但是這樣可以避免我的MAIL SERVER 不被RELY嗎?因為我的SERVER的enable SMTP認證沒開啟才能寄出去,開啟的話,一樣寄不出。
.......
應該可以設定成只有本機可以Relay
不過這樣就不能用其他電腦寄信了


下面是引用chris710908於2005-05-29 14:21發表的 :
4.大大說的imap_open()事怎樣的方式,有什麼限制嗎,我的MAIL SERVER好像沒看到imap這個選項?
.......
類似pop3看信用的
php的imap_open()函式可以用帳號密碼開啟就比較方便
效果跟之前的pop3認證差不多


下面是引用chris710908於2005-05-29 14:21發表的 :
5.我的SERVER應該是可以支援SMTP認證的~因為我用類似OUTLOOKㄉ軟體寄發信~都有用SMTP認證
只是在PHP的環境下用程式既不出去~這跟PHP.INI有關係ㄇ?因為這檔案裡面不支援認證
SMTP認證應該跟PHP.INI沒關係

另外試了一下ArGoSoft Mail Server
2005/5/29 下午 05:49:48 - (   3) 220 ArGoSoft Mail Server Freeware, Version 1.8 (1.8.7.8)
2005/5/29 下午 05:49:52 - (   3) AUTH LOGIN
2005/5/29 下午 05:49:52 - (   3) 502 Unknown command
2005/5/29 下午 05:50:05 - (   3) EHLO localhost
2005/5/29 下午 05:50:05 - (   3) 250-Welcome [127.0.0.1], pleased to meet you
2005/5/29 下午 05:50:05 - (   3) 250-AUTH=LOGIN
2005/5/29 下午 05:50:05 - (   3) 250-AUTH LOGIN
2005/5/29 下午 05:50:05 - (   3) 250-SIZE 5242880
2005/5/29 下午 05:50:05 - (   3) 250 HELP
2005/5/29 下午 05:50:15 - (   3) AUTH LOGIN
2005/5/29 下午 05:50:15 - (   3) 334 VXNlcm5hbWU6

所以我覺得
把刪掉的 //1、EHLO,期待返回220或者250
array("EHLO ".$loc_host.$lb,"220,250","HELO error: "),
補回去
應該就可以用了
我這邊不方便測試
您試試看吧

獻花 x0
引用 | 編輯 chris710908
2005-05-29 20:14
16樓
  
恩~我試過很多次了~~把那段複製過去後~~然後SERVER也開SMTP認證
網頁已經可以正常運作了,部會出現錯誤訊息~只是信還是寄不出去
算了囉~~小弟放棄了~反正先可以寄就好囉~
那如果被不明人士RELAY的話~我的電腦會有危險ㄇ(比如被植入病毒)
因為我用的這套軟體好像沒有限本機才能RELAY的功能~~
---------------------------------------------------------------------
謝謝大大熱心的教學喔~~讓我受益良多ㄋ 表情

獻花 x0
引用 | 編輯 xxxzzz
2005-05-29 23:19
17樓
  
下面是引用chris710908於2005-05-29 20:14發表的 :
恩~我試過很多次了~~把那段複製過去後~~然後SERVER也開SMTP認證
網頁已經可以正常運作了,部會出現錯誤訊息~只是信還是寄不出去
算了囉~~小弟放棄了~反正先可以寄就好囉~
那如果被不明人士RELAY的話~我的電腦會有危險ㄇ(比如被植入病毒)
因為我用的這套軟體好像沒有限本機才能RELAY的功能~~
.......
我知道您為什麼沒錯誤訊息但開認證還是寄不出了
因為上面的程式確認帳號密碼認證完後...
連線就關閉了
  //關閉連接
  @fclose($fp);
再來執行的mail()函式寄信,當然寄不出了
之前我測試的機器可以在本機不用認證寄信,所以都沒發現 表情

所以我想如果把@fclose($fp);改在mail()之後不知道可不可行
不知道mail()會不會繼續用fsockopen()開的連線?
(目前沒合適的環境可測試,如果您有試,記得告訴我喔 表情

另外一個方法就是
把資料傳給最初3樓的程式寄
(我想這樣應該可以...可是您似乎試過3樓的程式開SMTP認證不能用?)

其實這些我也是第一次試...也不太懂... 表情

獻花 x0
引用 | 編輯 chris710908
2005-05-30 17:48
18樓
  
我也試過了將@fclose($fp);放到後面了~
可是還是出現Error: [10054] Connection reset by peer
會是我是虛擬IP的關係嗎?可是我有開啟PORT25跟110阿~
表情 還是不成功~~阿勒~我在試試看ㄅ~謝囉 表情

獻花 x0
引用 | 編輯 shing3728
2010-09-11 10:42
19樓
  
明白了 ^^
謝謝!! 表情 表情

獻花 x0