400错误的请求:无法找出请求问题

时间:2019-09-09 09:55:22

标签: php microsoft-graph

我必须使用prestashop读取OneDrive工作表中的文件。 我无法在composer中使用microsoft / microsoft-graph数据包,因为它需要耗时v6,并且prestashop锁定在v5,因此我自己操纵了该请求,但似乎缺少了某些东西。

我弄清楚了凭据,我有访问令牌(没有令牌或随机字符串会给我一个401错误)。

现在,我正在尝试读取文件,但比这更容易的是,我无法在驱动器中列出最近的文件。 我可以在图形浏览器上进行操作(连接蜂鸣器),然后执行我想做的任何事情,但是在代码中我总是得到“ 400错误的错误请求”,而没有其他细节。

这是我的代码,如果您能指出正确的方向?

        $url = 'https://graph.microsoft.com/v1.0/me/drive/recent';
        $req = $guzzle->get($url, [
            'headers' => [
                'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.2 (KHTML, like Gecko) Chrome/5.0.342.3 Safari/533.2',
                'Accept'     => 'application/json, text/plain, */*',
                'Authorization' => 'Bearer ' . $accessToken,
            ],
            'body' => [
            ],
        ]);

编辑:

问题似乎与授权有关,这里是代码:

<?php
// 1/ retrieve the access token

        $guzzle = new \GuzzleHttp\Client();
        $url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
        $token = json_decode($guzzle->post($url, [
            'body' => [
                'client_id' => $clientId,
                'client_secret' => $clientSecret,
                'resource' => 'https://graph.microsoft.com/',
                'grant_type' => 'client_credentials',
                //should I use this
                'roles'=>[
                    "Sites.Read.All",
                    "Files.Read.All"
                ],
                //or this?
                'scp' => 'Sites.Read.All Files.Read.All'
            ],
        ])->getBody()->getContents());
        $access_token = $token->access_token;

// 2/ read file content
        $userId = 'email@domain.fr';
        $url = 'https://graph.microsoft.com/v1.0/users/' . $userId . '/drive/items/##FILE_ID##/workbook/worksheets(\'Export\')/range(address=\'a2:d4\')?$select=values';
        //$url = 'https://graph.microsoft.com/v1.0/users/' . $userId . '/drive/list';

        $guzzle = new \GuzzleHttp\Client();
        $req = $guzzle->get($url, [
            'headers' => [
                'Authorization' => 'Bearer ' . $accessToken,
            ]

        ]);
// this return a 403 forbidden
        $ret = json_decode($req->getBody()->getContents());

1 个答案:

答案 0 :(得分:0)

您很有可能通过Client credentials grant流获取访问令牌(应用程序许可令牌),在这种情况下,存在没有 Me上下文,因为它表示已登录的用户上下文(仅适用于delegated permission token)。

对于应用程序权限令牌,需要明确指定用户,例如:

要调用List recent files endpoint,至少需要Files.Read.AllSites.Read.All权限级别。

enter image description here

一旦获得 同意权限,如下所示

enter image description here

roles声明应包含以下权限列表:

"roles": [
    "Sites.Read.All",
    "Files.Read.All"
  ]

enter image description here

$userId = "<username>@<tenant>.onmicrosoft.com";
$url = 'https://graph.microsoft.com/v1.0/users/' . $userId . '/drive/recent';
$guzzle = new Client();
$headers = ['Authorization'=>'Bearer ' . $accessToken];
$response = $guzzle->get($url,['headers' => $headers]);
$json = json_decode($response->getBody()->getContents(),true);

要确定访问令牌是委派的还是应用程序许可的,可以使用jwt.io服务,例如:

对于应用程序权限令牌,该权限在roles声明中提供:

enter image description here

对于委托权限令牌,权限是通过scp声明指定的

enter image description here

如何获取访问令牌

function getAccessToken($tenantId, $clientId, $clientSecret){
    $guzzle = new Client();
    $url = 'https://login.microsoftonline.com/' . $tenantId . '/oauth2/token?api-version=1.0';
    $token = json_decode($guzzle->post($url, [
        'form_params' => [
            'client_id' => $clientId,
            'client_secret' => $clientSecret,
            'resource' => 'https://graph.microsoft.com/',
            'grant_type' => 'client_credentials'
        ],
    ])->getBody()->getContents());
    return $token->access_token;
}