Login with Microsoft Account in PHP

Microsoft enables web applications to allow users login with their outlook or Microsoft account via OAuth 2.0 system. Learn how to implement login with Microsoft account in PHP using Microsoft identity platform in simple steps.

Login with Microsoft Account in PHP

Microsoft identity platform provides OAuth authentication just like login with Google OAuth and login with GitHub OAuth. With Microsoft's identity platform we can allow users to sign in with Microsoft account without having to fill out long registration form. This post demonstrates how to implement login with Microsoft in a PHP application in simple steps. To implement login with Microsoft we will create following files:

  1. constants.php: The constants file to store our Microsoft credentials.
  2. microsoft-oauth-client.php: A PHP class to make API requests to Microsoft endpoints.
  3. index.php: The HTML file with Microsoft login button.
  4. logout.php: A PHP file to allow user to logout from Microsoft.
  5. style.css: The CSS stylesheet for HTML page and login button.
 

How to Integrate Login with Microsoft Account in PHP

In order to allow users to login with Microsoft account in PHP application we need to follow some simple steps. We need an Azure Application, Microsoft client ID and client secret, prepare Microsoft authorization URL to fetch Microsoft OAuth code, fetch Microsoft OAuth token for code and finally request user data from Microsoft graph API with an API request. Following are the steps to implement sign in with Microsoft in PHP:

 

Step 1: Register Microsoft Azure Application

To allow users to login with their Microsoft account we first need to register Microsoft Azure App in app registration portal. We then need application id, directory id, client id and client secret for our API requests. 

  • Go to the Microsoft Azure App registration portal.
  • Navigate to Azure Active Directory ➜ App Registrations ➜ New Registration.
  • Enter App Name for your application.
  • Enter the Redirect URI which is the URL of web application user will be redirected to after authorization.
  • After our app registration we need application id, directory id, client id and client secret to make API request to Microsoft from our PHP web application.
  • Client id and client secret can be created under section "Certificates & Secrets".
 

Step 2: Save Microsoft Client ID and Client Secret

Next we need to store our Microsoft client id and client secret in order to make API requests to Microsoft endpoints. 

constants.php

<?php
define('BASE_URL', 'https://' . filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_URL) . '/');
define('APPLICATION_ID', 'YOUR_MICROSOFT_APPLICATION_ID');
define('DIRECTORY_ID', 'YOUR_MICROSOFT_DIRECTORY_ID');
define('CLIENT_ID', 'YOUR_MICROSOFT_CLIENT_ID');
define('CLIENT_SECRET', 'YOUR_MICROSOFT_CLIENT_SECRET');
 

Step 3: Create a Microsoft OAuth Client Class

We need a centralized PHP class to make API requests to Microsoft endpoints. Using a PHP class will avoid bloated index file. The class will contain two public methods get_access_token() to retrieve access token from Microsoft and get_authenticated_user() to fetch Microsoft graph user information of authenticated user. Both methods will utitlize a private function curl_request() to make cURL requests.

  • Add two private class properties $client_id and $client_secret for use in our class methods.
  • Add a method get_access_token() to fetch access token from Microsoft authorization endpoint URL for a provided oauth code.
  • Add a method get_authenticated_user() to fetch data of authenticated user from Microsoft graph user endpoint.
  • Finally add a private method curl_request() to handle API requests and responses. This method will send a cURL request to Microsoft API endpoints provided as a parameter.

microsoft-oauth-client.php

<?php

class microsoft_oauth_client
{
private string $client_id;
private string $client_secret;

public function __construct($client_id, $client_secret)
{
$this->client_id = $client_id;
$this->client_secret = $client_secret;
}

/**
* @param string $oauth_code
* @param string $redirect_uri
* @return mixed
* @throws Exception
*/
public function get_access_token(string $oauth_code, string $redirect_uri): mixed
{
$api_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';

$headers = [
'content-type' => 'application/x-www-form-urlencoded'
];

$body_data = http_build_query([
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
'code' => $oauth_code,
'scope' => 'https://graph.microsoft.com/.default',
'redirect_uri' => $redirect_uri,
'grant_type' => 'authorization_code',
]);

$response = json_decode($this->curl_request($api_url, 'POST', $headers, $body_data));

return $response->access_token;
}

/**
* @param string $access_token
* @return mixed
* @throws Exception
*/
public function get_authenticated_user(string $access_token): mixed
{
$api_url = 'https://graph.microsoft.com/v1.0/me';

return json_decode($this->curl_request($api_url, 'GET',
[
'Authorization' => sprintf('Bearer %s', $access_token),
]
));

}

/**
* @param string $url
* @param string $method
* @param array $headers
* @param array|string $body
* @param array $curl_options
* @return bool|string
* @throws Exception
*/
private function curl_request(string $url, string $method = 'GET', array $headers = [], array|string $body = [], array $curl_options = []): bool|string
{
$curl = curl_init();

array_change_key_case($headers, CASE_LOWER);

$headers = array_merge(['accept' => 'application/json'], $headers);

curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_TIMEOUT, 0);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

if (str_starts_with($url, 'https://')) {
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
}

// If any headers are set, add them to curl request
if (!empty($headers)) {
curl_setopt($curl, CURLOPT_HTTPHEADER, array_map(function ($key, $value) {
return $key . ': ' . $value;
}, array_keys($headers), array_values($headers)));
}

// Set the request type , GET, POST, PUT or DELETE
switch (strtoupper($method)) {
case 'POST':
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
break;
case 'PUT':
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'PUT');
break;
case 'DELETE':
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
default:
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
break;
}

// Add content/body data to send with request
if (!empty($body)) {
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
}

// Any extra curl options to add to curl object
if (!empty($curl_options)) {
foreach ($curl_options as $option_key => $option_value) {
curl_setopt($curl, $option_key, $option_value);
}
}

$response = curl_exec($curl);

$error = curl_error($curl);

$error_code = curl_errno($curl);

$status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);

if ($error_code > 0) {
throw new Exception($error, $error_code);
}

if ($status_code !== 200) {
throw new Exception($response, $status_code);
}

curl_close($curl);

return $response;
}
}
 

Step 4: Create a Login with Microsoft Button

Next we need our main HTML file as a user interface with login with Microsoft button to allow users to sign in. The flow will be as follow:

  • Start a session on very top of page if it is not already started.
  • Include constants file and Microsoft client class.
  • Create $microsoft_oauth_client instance providing the client id, client secret.
  • Check access token is already in session then fetch authenticated user details from Microsoft.
  • Check in URL if there is a "code" query parameter set, which is added when user is redirected back from Microsoft authorization page. Get the access token from Microsoft for given oAuth code and redirect user to same page.
  • In HTML check if access token is set in session then user details are already fetched and displayed.
  • Display the login with Microsoft button if access token is not set in session.

index.php

<?php
if (!session_id()) {
session_start();
}

include_once 'constants.php';
include_once 'microsoft-oauth-client.php';

$microsoft_oauth_client = new microsoft_oauth_client(CLIENT_ID, CLIENT_SECRET);

if (isset($_SESSION['access_token'])) {
$user = $microsoft_oauth_client->get_authenticated_user($_SESSION['access_token']);

/**
* YOU CAN STORE USER INFORMATION TO DATABASE HERE
*/
}

$code = filter_input(INPUT_GET, 'code');

if (!empty($code)) {
$access_token = $microsoft_oauth_client->get_access_token(BASE_URL . 'login-with-microsoft-account-in-php');

$_SESSION['access_token'] = $access_token;

header('location: ' . BASE_URL . 'login-with-microsoft-account-in-php');
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Login with Microsoft Account in PHP - Demo</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
<meta content="width=device-width, initial-scale=1, maximum-scale=1" name="viewport"/>
<link rel="stylesheet" href="css/style.css"/>
</head>
<body>
<section class="section py-4">
<div class="container">
<?php if (isset($_SESSION['access_token'])) { ?>
<h3>You are logged in as:</h3>
<div class="user-details-container">
<div class="user-details">
<div>
<label>User ID:</label>
<span><?= $user->id; ?></span>
</div>
<div>
<label>Name:</label>
<span><?= $user->name; ?></span>
</div>
<div>
<a href="logout.php" rel="nofollow">Logout</a>
</div>
</div>
</div>
<?php } else { ?>
<a href="<?= sprintf('https://login.microsoftonline.com/common/oauth2/v2.0/authorize?%s', http_build_query([
'client_id' => CLIENT_ID,
'response_type' => 'code',
'response_mode' => 'query',
'scope' => 'openid profile email offline_access User.Read',
'redirect_uri' => BASE_URL . 'login-with-microsoft-account-in-php',
])); ?>" class="btn-microsoft" rel="nofollow">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M9.16675 9.1665H2.50008L2.50008 2.49984L9.16675 2.49984V9.1665Z" fill="#FF5722"/>
<path d="M17.5 9.1665H10.8333V2.49984L17.5 2.49984V9.1665Z" fill="#4CAF50"/>
<path d="M17.5 17.5H10.8333V10.8333H17.5V17.5Z" fill="#FFC107"/>
<path d="M9.16675 17.5H2.50008L2.50008 10.8333H9.16675V17.5Z" fill="#03A9F4"/>
</svg>

<span>Login with Microsoft</span>
</a>
<?php } ?>
</div>
</section>
</body>
</html>
 

Step 5: Create Logout From Microsoft OAuth (PHP)

Next we create a PHP file to allow user to logout from our web application and redirect user to Microsoft logout URL.

logout.php

<?php
if (!session_id()) {
session_start();
}

include_once 'constants.php';

unset($_SESSION['access_token']);

header('Location:' . sprintf('https://login.microsoftonline.com/common/oauth2/v2.0/logout?post_logout_redirect_uri=%s', urlencode(BASE_URL . 'login-with-microsoft-account-in-php')));
 

Step 6: Add CSS Styles for Microsoft HTML

Next we add CSS styles for index.php which contains the signin with Microsoft button and Microsoft user graph summary.

style.css

* {
box-sizing: border-box;
text-decoration: none;
}
html,body {
margin: 0;
padding: 0;
}
body {
background-color: #f6f6f6;
font-family: "Segoe UI", "Roboto", "Helvetica", sans-serif;
font-size: 15px;
font-weight: normal;
font-style: normal;
line-height: 1.5;
}
.container {
width: 100%;
max-width: 1140px;
margin-right: auto;
margin-left: auto;
padding-right: 15px;
padding-left: 15px;
}
.py-4 {
padding-top: 1rem;
padding-bottom: 1rem;
}
.user-details-container {
background-color: #ffffff;
border: 1px solid #dddddd;
display: inline-flex;
gap: 1rem;
padding: 1rem;
}
.btn-microsoft{
background-color: #ffffff;
display: inline-block;
color: #1f2328;
border: 1px solid #1f2328;
padding: 0.5rem 1rem;
}
.btn-microsoft:hover{
background-color: #1f2328;
color: #ffffff;
}
.btn-microsoft svg{
vertical-align: middle;
}
.btn-microsoft span{
display: inline-block;
margin-left: 0.5rem;
}

Following these steps, we can now securely implement Login with Microsoft Account in PHP using OAuth 2.0 and allow users to sign in with Outlook or any Microsoft account without manual registration.