Access Outlook email in PHP using imap and OAuth

883 Views Asked by At

Due to Microsoft removing Basic Auth from IMAP connections, we are converting our PHP code to use microsoft's oauth api and the external library: php imap.

We have managed to successfully get the access_token using the api and provide it to the library like so:

It works fine for two consecutive runs of the script, but for some reason, any time i run the same code after that, it doesn't let us connect, it returns an operation timeout error.

Error:

stream_socket_client(): unable to connect to ssl://outlook.office365.com:993 (Operation timed out) in php-imap/src/Connection/Protocols/Protocol.php:204

Code:

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

private function getAccessTokenUsingRefreshToken()
    {
        $CLIENT_ID      = $this->azure_settings['client_id'];
        $CLIENT_SECRET  = $this->azure_settings['secret_value'];
        $TENANT         = $this->azure_settings['tenant_id'];
        $REFRESH_TOKEN  = $this->azure_settings['refresh_token'];

        $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 !!!
        //  NOT IN LOCALHOST ? ERASE IT !
        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false);

        $result = curl_exec($ch);
        $access_token = json_decode($result)->access_token;

        return $access_token;
    }
0

There are 0 best solutions below