[求助]请问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