Microsoft Graph API OAuth 2.0 authorization - Get Access Token
In this article, you will be learning how to get MS Graph API access token in Laravel using Microsoft Graph APIs step by step.
So before getting started with creating or getting the access token from MS Graph API, Install or create the authentication in Laravel and then get started.
Note: before getting started please get your Microsoft Client ID and Client Secret. Click here to get
You will also learn, how to Refresh the access_token and how to get the Profile Detail in Laravel at Step 5.
Step 1: Provide the credentials in .env file
APP_URL=http://localhost:8000
SPA_URL=http://localhost:3000
MICROSOFT_CLIENT_ID="XXXXX-XXXX-XXXX-b579-aXXXX0cae641"
MICROSOFT_CLIENT_SECRET="vnCXX~XXXXXXXXXXXXX.zXMXoawEuFYQDCCCCCCCXXXXXXXXX"
MICROSOFT_REDIRECT_URI="${SPA_URL}/auth/microsoft/callback" # (On Javascript Application - Vue,React,Angular,etc)
# MICROSOFT_REDIRECT_URI="${APP_URL}/v1/ms-graph/microsoft/callback" # (On Laravel Application)
MICROSOFT_TENANT_ID="common"
MICROSOFT_LOGOUT_REDIRECT_URI="${SPA_URL}" # (On Javascript Application - Vue,React,Angular,etc)
# MICROSOFT_LOGOUT_REDIRECT_URI="${APP_URL}" # (On Laravel Application)
Step 2: Create a migration to store Microsoft Graph Token
Create migration using artisan command:
php artisan make:migration create_ms_graph_tokens_table
After successfully creating the migration, let's open ms_graph_tokens file from the following path: "database /migrations /2024_01_07_100005_create_ms_graph_tokens_table.php"
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('ms_graph_tokens', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id');
$table->string('token_type');
$table->mediumText('access_token');
$table->mediumText('refresh_token')->nullable();
$table->integer('expires_in')->nullable(); // in seconds
$table->timestamp('expiry_time')->nullable();
$table->mediumText('authorization_code');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('ms_graph_tokens');
}
};
Let's migrate the table using the following command:
php artisan migrate
Step 3: Create a Model
php artisan make:model MsGraphToken
Open MsGraphToken.php file and paste the below code:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class MsGraphToken extends Model
{
use HasFactory;
protected $table = 'ms_graph_tokens';
protected $fillable = [
'user_id',
'token_type',
'access_token',
'refresh_token',
'expires_in',
'expiry_time',
'authorization_code',
];
}
Now open User.php Model from the following path: "app/ Models/ User.php" and paste the below given relationship.
use App\Models\MsGraphToken;
class User extends Authenticatable{
// ... your existing code
public function msGraphToken()
{
return $this->hasOne(MsGraphToken::class, 'user_id', 'id');
}
}
Step 4: Create a Controller named MsGraphAuthController and paste the below code
php artisan make:controller MsGraphAuthController
After success creating the controller, open the MsGraphAuthController.php file from path: "app/ Http/ Controllers/ MicrosoftGraphAuthController.php"
<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Models\MsGraphToken;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Http;
class MsGraphAuthController extends Controller
{
public function redirectToMicrosoft()
{
// Redirect the user to Microsoft login page for authentication
$redirectUrl = 'https://login.microsoftonline.com/' . env('MICROSOFT_TENANT_ID') . '/oauth2/v2.0/authorize?client_id=' . env('MICROSOFT_CLIENT_ID') . '&redirect_uri=' . urlencode(env('MICROSOFT_REDIRECT_URI')) . '&response_type=code&scope=' . urlencode('openid profile email offline_access https://graph.microsoft.com/.default');
return response()->json(['redirectUrl' => $redirectUrl]);
}
public function handleMsCallback(Request $request)
{
// Extract the authorization code from the request
$authorizationCode = $request->code;
// Make a request to exchange the authorization code for an access token
$response = Http::asForm()->post('https://login.microsoftonline.com/'.env('MICROSOFT_TENANT_ID').'/oauth2/v2.0/token', [
'client_id' => env('MICROSOFT_CLIENT_ID'),
'client_secret' => env('MICROSOFT_CLIENT_SECRET'),
'code' => $authorizationCode,
'redirect_uri' => env('MICROSOFT_REDIRECT_URI'),
'grant_type' => 'authorization_code',
]);
$tokenResponse = $response->json();
if ($response->json('access_token')) {
$tokenResponse = $response->json();
$tokenType = $response->json('token_type');
$accessToken = $response->json('access_token');
$refreshToken = $response->json('refresh_token');
$expiresIn = $response->json('expires_in');
$expiryTime = Carbon::now()->addSeconds($expiresIn);
MsGraphToken::create([
'user_id' => auth()->user()->id,
'token_type' => $tokenType,
'access_token' => $accessToken,
'refresh_token' => $refreshToken,
'expires_in' => $expiresIn,
'expiry_time' => $expiryTime,
'authorization_code' => $authorizationCode,
]);
return response()->json([
'status' => 'success',
'message' => 'MsGraph Token Authentication successful'
], 200);
}else{
return response()->json([
'status' => 'error',
'message' => 'Something went wrong: MsGraph Token Authorization Code',
'data' => $tokenResponse,
], 200);
}
}
public function signOut()
{
$msAccessTokenData = MsGraphToken::where('user_id', auth()->id())->first();
$msAccessTokenData->delete();
$redirectUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/logout?post_logout_redirect_uri=' . env('MICROSOFT_LOGOUT_REDIRECT_URI');
return response()->json(['redirectUrl' => $redirectUrl]);
}
}
Step 5: Create a Controller named MsGraphController.php and paste the below code
<?php
namespace App\Http\Controllers;
use Carbon\Carbon;
use App\Models\MsGraphToken;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Http;
class MsGraphController extends Controller
{
public function profile()
{
$user = Auth::user();
$userProfileResponse = Http::withToken($user->msGraphToken->access_token)->get('https://graph.microsoft.com/v1.0/me');
if ($userProfileResponse->json('mail') > '') {
$response = $userProfileResponse->json();
return response()->json([
'message' => 'Profile fetched',
], 200);
}
}
public function checkIsAccessTokenExpired()
{
$user = Auth::user();
if($user->msGraphToken){
// Check if the access token is expired
if (strtotime($user->msGraphToken->expiry_time) < time()) {
// Access token is expired, refresh token
$refreshToken = $user->msGraphToken->refresh_token;
$newAccessToken = Http::asForm()->post('https://login.microsoftonline.com/'.env('MICROSOFT_TENANT_ID').'/oauth2/v2.0/token', [
'client_id' => env('MICROSOFT_CLIENT_ID'),
'client_secret' => env('MICROSOFT_CLIENT_SECRET'),
'refresh_token' => $refreshToken,
'grant_type' => 'refresh_token',
]);
if($newAccessToken->successful()){
// Update the database with the new access token
MsGraphToken::where('user_id', Auth::user()->id)->update([
'access_token' => $newAccessToken['access_token'],
'refresh_token' => $newAccessToken['refresh_token'],
'expires_in' => $newAccessToken['expires_in'],
'expiry_time' => Carbon::now()->addSeconds($newAccessToken['expires_in']),
]);
return response()->json([
'message' => 'New Authentication Successful',
'data' => 'token_validated',
]);
}else{
return response()->json([
'message' => 'Something Went Wrong!. Refresh Token',
'data' => 'invalid_refresh_token',
'status' => 'error',
'error' => 'error',
]);
}
}else{
return response()->json([
'message' => 'Authentication successful',
'data' => 'token_validated',
]);
}
}else{
return response()->json([
'error' => 'access_token_not_configured',
'data' => 'access_token_not_configured',
'message' => 'Microsoft configuration not completed',
]);
}
}
}
Step 6: Create a Route API in routes/api.php
use App\Http\Controllers\MsGraphAuthController;
use App\Http\Controllers\MsGraphController;
Route::prefix('v1/ms-graph')->group( function () {
Route::get('/microsoft', [MsGraphAuthController::class, 'redirectToMicrosoft']);
Route::post('/microsoft/callback', [MsGraphAuthController::class, 'handleMsCallback']);
Route::get('/microsoft/logout', [MsGraphAuthController::class, 'signOut']);
Route::get('/profile', [MsGraphController::class, 'profile']);
Route::get('/auth-check', [MsGraphController::class, 'checkIsAccessTokenExpired']);
});
That's it. you are ready to use this functionality to get Microsoft Access Token and use it as per your requirement in the frontend application like Vue Js, React Js, Angular, Nuxt, etc.