Загрузка файлов из личного OneDrive с использованием Python - PullRequest
1 голос
/ 30 сентября 2019

У меня есть сценарий Python, который периодически запускается на компьютере с AWS EC2 Ubuntu.

Этот сценарий считывает данные из некоторых файлов и иногда изменяет данные в них.

Я хочу загрузить этифайлы из OneDrive, делайте с ними свое дело и загружайте их обратно в OneDrive.

Я хочу, чтобы это делалось автоматически, без необходимости для пользователя утверждать любые логин или учетные данные. Я могу сделать это один раз (то есть подтвердить вход в систему при первом запуске), но все остальное должно запускаться автоматически, без повторного запроса разрешений (если, конечно, разрешения не меняются).

Что такоелучший способ сделать это?

Я читал документацию по Microsoft Graph API, но я борюсь с аутентификацией. Я создал приложение в Azure AAD, дал образец разрешений (для тестирования) и создал секретные учетные данные.

1 Ответ

0 голосов
/ 06 октября 2019

Мне удалось это сделать. Я не уверен, что это лучший способ, но сейчас он работает. Он запускается автоматически каждый час, и мне не нужно его трогать.

Я следил за информацией на https://docs.microsoft.com/en-gb/azure/active-directory/develop/v2-oauth2-auth-code-flow

Это то, что я сделал.

Портал Azure

  • Создание приложения. Azure Active Directory -> Регистрация приложений -> Приложения из личной учетной записи
  • В Поддерживаемые типы учетных записей выберите тот, который имеет личных учетных записей Microsoft .
  • В URI перенаправления выберите Общий клиент / собственный . Мы добавим конкретный URI позже.
  • В сведениях о приложении, в разделе Обзор , обратите внимание на ID приложения (клиента) . Это понадобится нам позже.
  • В разделе Аутентификация , нажмите Добавить платформу и выберите Рабочий стол + устройства . Вы можете использовать свои собственные, я выбрал одно из предложенных: https://login.microsoftonline.com/common/oauth2/nativeclient
  • В разделе API-разрешения вам необходимо добавить все разрешения, которые будет использовать ваше приложение. Я добавил User.Read , Files.ReadWrite и offline_access . offline_access должен иметь возможность получить токен обновления , который будет иметь решающее значение для поддержания работы приложения без запроса входа пользователя.
  • Я не создаллюбой сертификат или секрет .

Web

Похоже, мы впервые получили токендолжен использовать браузер или эмулировать что-то подобное.

Должен быть программный способ сделать это, но я понятия не имел, как это сделать. Я также думал об использовании Selenium для этого, но так как это только один раз, и мое приложение будет запрашивать токены каждый час (сохраняя токены свежими), я отказался от этой идеи.

Если мы добавим новые разрешения, имеющиеся у нас токены станут недействительными, и нам придется снова выполнять эту ручную часть.

  • Откройте браузер и перейдите по указанному ниже URL-адресу. Используйте Scopes и URI перенаправления , которые вы настроили на портале Azure.

https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=your_app_client_id&response_type=code&redirect_uri=https%3A%2F%2Flogin.microsoftonline.com%2Fcommon%2Foauth2%2Fnativeclient&response_mode=query&scope=User.Read%20offline_access%20Files.ReadWrite

Этот URL будет перенаправить вас на URI перенаправления , который вы настроили, и с кодом = что-то в URL. Скопируйте это что-то .

  • Сделайте запрос POST с закодированным URL-адресом типа FORM. Для этого я использовал https://reqbin.com/.

Конечная точка : https://login.microsoftonline.com/common/oauth2/v2.0/token

URL-адрес формы : grant_type = authorization_code & client_id =your_app_client_id & code = use_the_code_returned_on_previous_step

Это вернет токен доступа и токен обновления. Храните жетон обновления где-нибудь. Я сохраняю его в файле.

Python

# Build the POST parameters
params = {
          'grant_type': 'refresh_token', 
          'client_id': your_app_client_id,
          'refresh_token': refresh_token_that_you_got_in_the_previous_step
         }

response = requests.post('https://login.microsoftonline.com/common/oauth2/v2.0/token', data=params)

access_token = response.json()['access_token']
new_refresh_token = response.json()['refresh_token']

# ^ Save somewhere the new refresh token. 
# I just overwrite the file with the new one. 
# This new one will be used next time.

header = {'Authorization': 'Bearer ' + access_token}

# Download the file
response = requests.get('https://graph.microsoft.com/v1.0/me/drive/root:' +
                         PATH_TO_FILE + '/' + FILE_NAME + ':/content', headers=header)

# Save the file in the disk 
with open(file_name, 'wb') as file:
    file.write(response.content)

Так что, в принципе, у меня всегда обновляется токен обновления.

Я вызываю конечную точку токена, используя этот токен обновления, и API дает мне токен доступа для использования во время текущего сеанса и новый токен обновления.

Я использую этот новый токен обновления в следующий развремя запуска программы и т. д.

...