使用Python从个人OneDrive下载文件

16
我有一个Python脚本定期在AWS EC2 Ubuntu机器上运行。
这个脚本从一些文件中读取数据,有时会更改它们的数据。
我想从OneDrive下载这些文件,对它们进行自己的操作,然后将它们上传回OneDrive。
我希望这一切都是自动完成的,不需要用户批准任何登录或凭据。我可以在第一次运行时处理登录(即批准登录),但其余部分必须自动运行,而不需要再次请求批准(除非权限发生更改)。
最好的方法是什么?
我一直在阅读Microsoft Graph API的文档,但我在身份验证部分遇到了困难。我在Azure AAD中创建了一个应用程序,给了示例权限(进行测试)并创建了一个秘密凭据。
2个回答

23

我成功地完成了它。我不确定这是否是最好的方法,但现在它正在运行。它每小时自动运行,我不需要去操作它。

我遵循了https://learn.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.ReadFiles.ReadWriteoffline_accessoffline_access是为了能够获取刷新令牌,这将对保持应用程序运行而不要求用户登录至关重要。
  • 我没有创建任何证书密码

Web

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

肯定有编程的方法可以做到这一点,但我不知道该如何实现。我也考虑过使用Selenium,但由于只需要一次,并且我的应用程序每小时都会请求令牌(保持令牌的新鲜),所以我放弃了这个想法。

如果我们添加新的权限,则我们拥有的令牌将变为无效状态,我们必须再次手动执行此步骤。

  • 打开浏览器并转到下面的URL。使用你在Azure门户中设置的ScopesRedirect 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.Read%20offline_access%20Files.ReadWrite

该URL将重定向您到设置的重定向URI,并在URL中带有code=something。请复制那个something

  • 使用类型为FORM URL编码的POST请求。我用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会给我一个访问令牌,在当前会话中使用,并提供一个新的刷新令牌。
下次运行程序时,我将使用这个新的刷新令牌,以此类推。

PATH_TO_FILE 可以是:"/Files/FolderName" FILE_NAME 可以是:"Text_file.txt" - Hugo Neves
@Aniruddh,上面的代码对你有用吗?文件夹里面的文件呢? - Learnings
@SPy 我的路径中也有空格,但我没有使用urllib.parse.quote。尝试使用以下方式调用get请求:https://graph.microsoft.com/v1.0/me/drive/root:/New Folder/Knox EARNSTSALV2020.xlsx:/content - Hugo Neves
在“进行POST请求”部分中,似乎redirect_uri是必填字段。https://learn.microsoft.com/en-gb/azure/active-directory/develop/v2-oauth2-auth-code-flow - Cabara
https://reqbin.com/ 将您的数据发送到他们的服务器,允许他们保存您的令牌。 - user3064538
显示剩余3条评论

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接