MS Graph выдает 401 при загрузке файла в общий ресурс OneDrive другого пользователя

avatar
DigitalOnion
8 августа 2021 в 22:23
174
1
0

3 дня работаю над этой простой штукой, нужен мудрый совет:

Мне нужно отправить файл в общую папку OneDrive другого пользователя из Node.js.

  • В Azure я убедился, что у меня есть соответствующие разрешения: Files.ReadWrite.All типа Application Files.ReadWrite.All типа Delegated

  • Также я добавил необязательные утверждения: act — статус учетной записи пользователя в тенанте — тип токена: Access

Затем я получаю токен доступа, вызывая MSAL ConfidentialClientApplication, а затем приобретаюTokenByClientCredential, например:

function generateTokenPromise() {
  let config = {
    auth: {
      clientId: applicationId,
      authority: msOnlineBaseUrl + '/' + tenantId,
      clientSecret: clientSecretValue,
    },
    system: {
      loggerOptions: {
        loggerCallback(loglevel, message, containsPii) {
          console.log(message);
        },
        piiLoggingEnabled: false,
        logLevel: msal.LogLevel.Verbose,
      }
    }
  };

  // Create msal application object
  let cca = new msal.ConfidentialClientApplication(config);

  let clientCredentialRequest = {
    tenant: tenantId, 
    client_id: applicationId,
    scopes: ["https://graph.microsoft.com/.default"],
    client_secret: clientSecretValue,
    azureRegion: "centralus",
    skipCache: true,
    grant_type: "client_credentials",
  };

  return cca.acquireTokenByClientCredential(clientCredentialRequest)
}

Токен хороший, он позволяет мне работать с учетной записью другого пользователя:

  • Я могу читать содержимое корневой и дочерней папок.
  • Я могу читать информацию об элементах диска, как о файлах, так и о папках.
  • Я могу создать папку в другой учетной записи.

Но когда я пытаюсь создать файл, приложение выдает мне код ошибки HTTP 401: Неавторизованный ответ об ошибке клиента. Что не имеет смысла. У меня правильная аутентификация, токен хороший, иначе он не позволял бы выполнять другие функции.

Чтобы создать запрос, я использую Node.js FormData с буфером. Я урезал код, пытаясь заставить его работать:

function uploadBinaryFile(req, res) {
  let token
  generateTokenPromise()
  .then(tokenResponse => {
    // token = tokenResponse.accessToken
    return receiveBinaryFilePromise(req)
  })
  .then(async buffer => {
    let microsoftUserId = 'LidiaH@appsname.onmicrosoft.com'
    let foundFolderName = 'found-folder'
    let foundFolderId = '01S2X...TOETQ'  // this is the found-folder's Folder Id
    let filename = "new-file.jpg"
    let url = new URL(`/users/${microsoftUserId}/drive/items/${foundFolderId}:/${filename}:/content`, msGraphBaseUrl)
    // let url = new URL(`/users/${microsoftUserId}/drive/root:/${foundFolderName}/${filename}:/content`, msGraphBaseUrl)
    
    let form = new FormData()
    // form.append('uploadFile',  buffer)
    form.append('field', 'a,b,c', 'blah.csv');    // TODO: this is a test, use the buffer later

    let headersConfig = {
      "Authorization": `Bearer ${token}`,
      ...form.getHeaders()
    }
    return axios({
      method: 'post',
      url: url.toString(),
      data: form,
      headers: headersConfig 
    })
  })
  .then(thing => {
    console.log('Success!')
  })
  .catch(error => {
    console.error(error)
  })
 }

Я с подозрением отношусь к тому, что делает axios для запуска запроса. Я пытался изменить headerConfig и URL-адрес, но у меня заканчиваются идеи и время.

Я также читал о FormData, но думаю, что это хорошо.

Вы знаете, как это сделать? Можете предложить статью? Работа вокруг? Некий путеводный свет в конце туннеля?

Спасибо Луис.

Источник
Mario Varchmin
9 августа 2021 в 06:26
0

Вы используете POST, в то время как документация предлагает использовать PUT. Вы когда-нибудь пытались загрузить файл через Postman?

DigitalOnion
10 августа 2021 в 14:24
0

@MarioVarchmin, ты был совершенно прав. Я изменил его на PUT, а затем попробовал в Postman. Добавил файл в Тело как Бинарный файл, потом попробовал, после исправления запроса заработало! Благодарю вас!

Mario Varchmin
10 августа 2021 в 14:26
0

Я рад слышать, что теперь это работает на вас.

AnsumanBal-MT
16 августа 2021 в 09:19
0

Здравствуйте @MarioVarchmin, не могли бы вы опубликовать свое предложение в качестве ответа, поскольку оно сработало для DigitalOnion и поможет другим членам сообщества.

Mario Varchmin
16 августа 2021 в 09:23
1

@ansumanBal-MT: Готово!

AnsumanBal-MT
16 августа 2021 в 09:28
0

@MarioVarchmin, спасибо!

Ответы (1)

avatar
Mario Varchmin
9 августа 2021 в 06:22
0

В документации (https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online) предлагается использовать PUT при использовании метода POST.