首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用OAuth连接邮箱办公室365

用OAuth连接邮箱办公室365
EN

Stack Overflow用户
提问于 2022-08-16 08:03:27
回答 1查看 3.7K关注 0票数 7

请原谅我的业余行为,无论是在php和堆栈溢出。我有一个PHP脚本,用于读取office 365邮箱中的电子邮件,为此,我使用标准连接:

$Inbox = imap_open('{Outlook.office365.com:993/imap/ssl}', 'mabal@mydomain.com', 'mypassword');

然后,为了阅读收到的新邮件,我使用了以下命令:

$UnRead = imap_search($Inbox, 'UNSEEN');

从20221001 -2022年10月1日起,微软将删除此身份验证,并要求进行身份验证.

我在Microsoft 注册了我的web应用程序,并尝试了几种设置。我做了很多研究,使我能够连接到邮箱,以便能够阅读邮件,而不需要与用户进行交互。我什么都没找到。

是否有人有一步一步的解决方案来检索绑定到"imap_open“的变量,或者您必须使用完全不同的系统。

谢谢你的帮助。

EN

回答 1

Stack Overflow用户

发布于 2022-11-18 14:27:12

对我和我的同事来说,这是一次疯狂的旅程,但我们找到了解决办法。

1-在Azure中配置邮箱

(这部分不是我做的,所以我帮不了你更多!)你需要:

  • 客户机Id
  • 租户Id
  • 秘密客户端
  • 重定向Uri (将其设置为
  • )

2-获取一个代码以获得一个令牌

构造这个url:

代码语言:javascript
运行
复制
$TENANT="5-48...";
$CLIENT_ID="c-9c-....";
$SCOPE="https://outlook.office365.com/IMAP.AccessAsUser.All";
$REDIRECT_URI="http://localhost/test_imap";

$authUri = 'https://login.microsoftonline.com/' . $TENANT
           . '/oauth2/v2.0/authorize?client_id=' . $CLIENT_ID
           . '&scope=' . $SCOPE
           . '&redirect_uri=' . urlencode($redirectUri)
           . '&response_type=code'
           . '&approval_prompt=auto';

echo($authUri);

转到链接,用密码连接到邮箱。一旦完成,您将被重定向到:http://localhost/test_imap?code=LmpxSnTw...&session_state=b5d713...

保存代码(删除末尾的“&”!)以及url中的会话状态。这些代码在几个小时后过期了!

3-获取访问令牌

代码语言:javascript
运行
复制
$CLIENT_ID="c-9c-....";
$CLIENT_SECRET="Y~tN...";
$TENANT="5-48...";
$SCOPE="https://outlook.office365.com/IMAP.AccessAsUser.All offline_access";
$CODE="LmpxSnTw...";
$SESSION="b5d713...";
$REDIRECT_URI="http://localhost/test_imap";

echo "Trying to authenticate the session..";

$url= "https://login.microsoftonline.com/$TENANT/oauth2/v2.0/token";

$param_post_curl = [ 
 'client_id'=>$CLIENT_ID,
 'scope'=>$SCOPE,
 'code'=>$CODE,
 'session_state'=>$SESSION,
 'client_secret'=>$CLIENT_SECRET,
 'redirect_uri'=>$REDIRECT_URI,
 'grant_type'=>'authorization_code' ];

$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($param_post_curl));
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);

$oResult=curl_exec($ch);

echo "result : \n";

var_dump($oResult);

作为回应的access_token将只运行几个小时。(如果您的脚本将在每天的basic上启动,则需要重新创建一个令牌。我将在第五部分向你们展示如何!将refresh_token保存在$oResult中。如果您没有"refresh_token“,那么您已经忘记将"offline_access”放在作用域中)

4-连接到邮箱

现在选择你最喜欢的图书馆;)!本例将使用webklex/php-imap (https://github.com/Webklex/php-imap)。

代码语言:javascript
运行
复制
include __DIR__.'/vendor/autoload.php'; 
    
use Webklex\PHPIMAP\ClientManager;

$access_token="EH.j8s5z8...";
    
//$cm = new ClientManager($options = ["options" => ["debug" => true]]);                     
$cm = new ClientManager();                      
$client = $cm->make([
    'host'          => 'outlook.office365.com',                
    'port'          => 993,
    'encryption'    => 'ssl',
    'validate_cert' => false,
    'username'      => 'mymailbox@domain.com',
    'password'      => $access_token,
    'protocol'      => 'imap',
    'authentication' => "oauth"
]);

try {
    //Connect to the IMAP Server
    $client->connect();
    $folder = $client->getFolder('INBOX');
    $all_messages = $folder->query()->all()->get();
    //DONE ! :D     
} catch (Exception $e) {
    echo 'Exception : ',  $e->getMessage(), "\n";
}

5-每天连接邮箱

代码语言:javascript
运行
复制
include __DIR__.'/vendor/autoload.php'; 
    
use Webklex\PHPIMAP\ClientManager;

$CLIENT_ID="c-9c-....";
$CLIENT_SECRET="Y~tN...";
$TENANT="5-48...";
$REFRESH_TOKEN="EebH9H8S7...";

$url= "https://login.microsoftonline.com/$TENANT/oauth2/v2.0/token";

$param_post_curl = [ 
 'client_id'=>$CLIENT_ID,
 'client_secret'=>$CLIENT_SECRET,
 'refresh_token'=>$REFRESH_TOKEN,
 'grant_type'=>'refresh_token' ];

$ch=curl_init();

curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_POSTFIELDS, http_build_query($param_post_curl));
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
//ONLY USE CURLOPT_SSL_VERIFYPEER AT FALSE IF YOU ARE IN LOCALHOST !!!
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);// NOT IN LOCALHOST ? ERASE IT !

$oResult=curl_exec($ch);

echo("Trying to get the token.... \n");

if(!empty($oResult)){
    
    echo("Connecting to the mail box... \n");
    
    //The token is a JSON object
    $array_php_resul = json_decode($oResult,true);
    $access_token = $array_php_resul["access_token"];
    if( !empty($access_token) ){

        //$cm = new ClientManager($options = ["options" => ["debug" => true]]);                     
        $cm = new ClientManager();                      
        $client = $cm->make([
            'host'          => 'outlook.office365.com',                
            'port'          => 993,
            'encryption'    => 'ssl',
            'validate_cert' => false,
            'username'      => 'mymailbox@domain.com',
            'password'      => $access_token,
            'protocol'      => 'imap',
            'authentication' => "oauth"
        ]);
        
        try {
            //Connect to the IMAP Server
            $client->connect();
        }catch (Exception $e) {
            echo 'Exception : ',  $e->getMessage(), "\n";
        }
    }
}   

我希望它能帮到你。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73370661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档