使用 Python 从个人 OneDrive 下载文件

Hug*_*ves 10 python onedrive microsoft-graph-api

我有一个在 AWS EC2 Ubuntu 机器上定期运行的 Python 脚本。

此脚本从某些文件读取数据,有时会更改其中的数据。

我想从 OneDrive 下载这些文件,用它们做我自己的事情,然后将它们上传回 OneDrive。

我希望这可以自动完成,而无需用户批准任何登录或凭据。我可以做一次(即在第一次运行时批准登录),但其余的必须自动运行,而无需再次请求批准(当然,除非权限发生变化)。

做这个的最好方式是什么?

我一直在阅读有关 Microsoft Graph API 的文档,但我在身份验证部分遇到了困难。我在 Azure AAD 中创建了一个应用程序,授予示例权限(用于测试)并创建了一个秘密凭据。

Hug*_*ves 12

我设法做到了。我不确定这是否是最好的方法,但它现在正在起作用。它每小时自动运行一次,我不需要触摸它。

我遵循了https://docs.microsoft.com/en-gb/azure/active-directory/develop/v2-oauth2-auth-code-flow上的信息

这就是我所做的。

Azure 门户

  • 创建应用程序。Azure Active Directory -> 应用程序注册 -> 来自个人帐户的应用程序
  • 支持的帐户类型中,选择具有个人 Microsoft 帐户的帐户类型
  • Redirect URI 中,选择Public client/native。我们稍后会添加特定的 URI。
  • 在应用程序详细信息的概述部分中,记下应用程序(客户端)ID。我们稍后会需要这个。
  • 身份验证部分中,单击添加平台并选择桌面 + 设备。您可以使用自己的,我选择了建议之一:https : //login.microsoftonline.com/common/oauth2/nativeclient
  • API 权限部分,您必须添加您的应用程序将使用的所有权限。我添加了User.ReadFiles.ReadWriteoffline_access。该offline_access是能够得到刷新令牌,这将是至关重要的,以保持应用程序,而不要求用户登录运行。
  • 我没有创建任何CertificateSecret

网络

看起来我们必须使用浏览器或模拟类似的东西才能第一次获得令牌。

必须有一种编程方式来做到这一点,但我不知道该怎么做。我也考虑过为此使用 Selenium,但由于它只有一次并且我的应用程序每小时都会请求令牌(保持令牌新鲜),我放弃了这个想法。

如果我们添加新的权限,我们拥有的令牌将失效,我们必须再次执行此手动部分。

  • 打开浏览器并转到下面的 URL。使用在 Azure 门户中设置的范围重定向 URI

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 20offline_access%20Files.ReadWrite

该网址会重定向你到重定向URI您设置并用代码=东西在URL中。复制那个东西

端点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)
Run Code Online (Sandbox Code Playgroud)

所以基本上,我总是更新刷新令牌。

我使用刷新令牌调用令牌端点,API 为我提供了在当前会话期间使用的访问令牌和新的刷新令牌。

下次运行程序时我会使用这个新的刷新令牌,依此类推。