Reputation: 21
I need a little help understanding how often I should be requesting an Access Token when using the Microsoft Graph API. I already have the Enterprise Application created with the proper permissions - everything is working as it should be but I'm not certain I'm correctly using it...
We have a custom Company Directory that loads user profile pictures and their Microsoft Teams presence for each user. Currently I'm requesting the access token on each page load. But is this necessary? Is there a more efficient way to do this such as storing the Access Token in a session? How long does the token last? I'm having a bit of trouble comprehending all this. Any guidance would be greatly appreciated.
I'm requesting the Access Token on each page load by calling a function getAccessToken().
//Get Microsoft Graph API Access Token
function getAccessToken() {
// Set up the request parameters
$clientId = "";
$clientSecret = "";
$tenant_id = "";
$grantType = "client_credentials";
$resource = "https://graph.microsoft.com";
$tokenEndpoint = "https://login.microsoftonline.com/$tenant_id/oauth2/token";
// Build the request body
$requestBody = "client_id=$clientId&client_secret=$clientSecret&grant_type=$grantType&resource=$resource";
// Set up the curl options
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenEndpoint);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
// Execute the request
$response = curl_exec($ch);
curl_close($ch);
// Extract the access token from the response
$responseJson = json_decode($response, true);
$accessToken = $responseJson["access_token"];
return $accessToken;
}
Then depending on the page loaded, I call the getAccessToken() function once at the top of my script and then perform numerous Microsoft Graph API calls for things like profile pictures, user data, and presence information.
Is this the correct way of leveraging the Access Token?
Upvotes: 1
Views: 1784
Reputation: 21
I came up with the following functions after looking at some other examples. I know it's not perfect and won't handle every token circumstance, but it's been working for me so far. Feel free to rip me apart - I'm not a developer. I'm just dangerous enough to hack things together.
function getAccessToken() {
//Generate a token if it doesn't already exist and store it in a session.
if (!isset($_SESSION['access_token']) || !isset($_SESSION['expires_on'])) {
$accessToken = generateAccessToken();
$_SESSION['access_token'] = $accessToken['access_token'];
$_SESSION['expires_on'] = $accessToken['expires_on'];
return $accessToken;
} else {
//check if token is expired or not
$expires_on = $_SESSION['expires_on']; // Unix timestamp
$current_time = time();
//Check if token expiry has passed and regenerate token. Othwerwise, return the stored token from the session variables.
if($current_time >= $expires_on){
$accessToken = generateAccessToken();
$_SESSION['access_token'] = $accessToken['access_token'];
$_SESSION['expires_on'] = $accessToken['expires_on'];
return $accessToken;
} Else {
return $_SESSION;
}
}
}
function generateAccessToken() {
// Set up the request parameters
global $clientId, $clientSecret, $tenant_id;
$grantType = "client_credentials";
$resource = "https://graph.microsoft.com";
$tokenEndpoint = "https://login.microsoftonline.com/$tenant_id/oauth2/token";
// Build the request body
$requestBody = "client_id=$clientId&client_secret=$clientSecret&grant_type=$grantType&resource=$resource";
// Set up the curl options
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $tokenEndpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $requestBody);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Execute the request
$response = curl_exec($ch);
curl_close($ch);
// Extract the access token from the response
$responseJson = json_decode($response, true);
//$accessToken = $responseJson["access_token"];
//return $accessToken;
return $responseJson;
}
And then I'm using the token to query the Microsoft Graph API. Here's an example of grabbing a user's profile photo using getUserPhotoFromGraphAPI([email protected]):
function getUserPhotoFromGraphAPI ($mail) {
// First, obtain an access token for the Microsoft Graph API
global $noProfilePicture;
//Get Access Token
$accessToken = getAccessToken();
// Next, use the Microsoft Graph API to get the user's profile picture
$ch = curl_init();
$url = 'https://graph.microsoft.com/v1.0/users/' . $mail . '/photo/$value';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer " . $accessToken['access_token']));
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$err = curl_error($ch);
curl_close($ch);
// The profile picture is returned as a binary stream.
//print_r($output);
//$json = json_decode($output);
if ($err) {
//echo "cURL Error #:" . $err;
return null;
}
else {
if($httpcode == 200) {
//The photo is returned in binary form, we need to convert it to Base64 for storage in MySQL
$dataUri = chunk_split(base64_encode($output));
$imageBase64 = "data:image/jpeg;base64,$dataUri";
//Return the file name
return $imageBase64;
} else {
//Return the no profile picture found file name from config.php
return $noProfilePicture;
}
}
}
Upvotes: 1