Source: https://stackoverflow.com/questions/73370661/php-connect-mailbox-office-365-with-oauth
1 – Configure your mail box in Azure
(I didn’t do this part so i can’t help you more than that ! )
Edit : Thanks to parampal-pooni, this link explains how to configurate in azure.
You will need :
- The client Id
- The tenant Id
- The secret client
- The redirect Uri (Set it to http://localhost/test_imap)
2 – Grab a code to get a token
Construct this url :
$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($REDIRECT_URI)
. '&response_type=code'
. '&approval_prompt=auto';
echo($authUri);
Go to the link, connect to the mail box with the passeword. Once it done, you will be redirect to : http://localhost/test_imap?code=LmpxSnTw…&session_state=b5d713….
Save the code (remove the ‘&’ at the end !) and the session state inside the url. These codes expired after a few hours !
When you are on this new page look inside the url, you should have htp:/localhost/test_imap?code=MyCodeIShouldSave&session_state=MySessionIShouldSave This is the $CODE and the $SESSION you are looking for for the step 3
3 – Get an access token
$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);
The access_token given in response is going to work only for a few hours. ( If your script is going to be launch on a daily basic you need to recreate a token. I’m going to show you how in the part 5 ! Save the refresh_token inside $oResult. (It are in the middle of the output).
If you don’t have the “refresh_token” you have forgot to put “offline_access” in the scope)
4 – Connect to the mail box
Now choose your favorite library ! We will use webklex/php-imap for this example (https://github.com/Webklex/php-imap)
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 – Connecting to the mail box everyday
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);
if( isset($array_php_resul["access_token"]) ){
$access_token = $array_php_resul["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";
}
}else{
echo('Error : '.$array_php_resul["error_description"]);
}
}
It will only connect to the mailbox, you then need to write some more code to get access to the mail. Look at https://github.com/Webklex/php-imap