I have a website where my clients can view their invoices and upload design assets related to the invoice. I want to create a PHP form which uploads the files to OneDrive, instead of storing them on our web server.
I have followed the instructions in this StackOverflow answer to get started.
I have created the app in Microsoft Azure, and entered the appropriate Application (client) ID, Object ID, and Directory (tenant) ID. I am using a client secret to authorize the application, and submitting a POST request using my account's email and password to get the access token.
The relevant code for my upload form looks like this:
if (isset($_FILES['uploads'])) {
$guzzle = new \GuzzleHttp\Client();
$tenantId = 'xxxxxx';
$clientId = 'xxxxxx';
$clientSecret = 'xxxxxx';
$url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token';
$user_token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'password',
'username' => 'xxxxxx@companydomain.com',
'password' => 'xxxxxx'
],
])->getBody()->getContents());
$user_accessToken = $user_token->access_token;
$graph = new Graph();
$graph->setAccessToken($user_accessToken);
foreach ($_FILES['uploads']['name'] as $key => $name) {
try {
$graph->createRequest(
"PUT", "/drive/root:/Documents/".$_FILES['uploads']['name'][$key].":/content"
)->upload(
$_FILES['uploads']['tmp_name'][$key]
);
} catch (Exception $e) {
var_dump($e);
}
}
}
This code throws an exception, showing the following error message when I try to upload a :
Client error: `PUT https://graph.microsoft.com/v1.0/drive/root:/Documents/Screen%20Shot%202022-10-30%20at%204.03.44%20PM.png:/content` resulted in a `403 Forbidden` response
In the Azure API Permissions, I have granted the Files.Read.All
, Files.ReadWrite.All
, and User.Read
permissions. However, when I check the access token in https://jwt.ms/, I just see "scp": "User.Read"
.
So it looks like my access token might not have the correct permissions, but I can see that I do have permissions to read and write files when I look at the API Permissions page in Azure.
How can I further debug this issue and find a solution to upload files from my server to OneDrive?
Thanks to Nikolay's comment, I added a scope
parameter to form_params
and that fixed it.
I also changed the grant_type
to client_credentials
, and removed the username/password authorization.
$user_token = json_decode($guzzle->post($url, [
'form_params' => [
'client_id' => $clientId,
'client_secret' => $clientSecret,
'resource' => 'https://graph.microsoft.com/',
'grant_type' => 'client_credentials',
'scope' => 'https://graph.microsoft.com/.default'
],
])->getBody()->getContents());
$user_accessToken = $user_token->access_token;