当前位置: 首页 > 知识库问答 >
问题:

HttpError 403请求时无返回”权限不足

宋华美
2023-03-14

从Gmail的电子邮件附件上载到Google Drive:

from __future__ import print_function
import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

import io
import base64
from googleapiclient.http import MediaIoBaseUpload
from time import sleep


q='has:attachment'
maxResults=int(input("Please specify the number of emails with attachments that you would like to see:"))

#for drive api---------------------------------------------------------------------------------

# If modifying these scopes, delete the file token.pickle.

creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
if os.path.exists('token_drive.pickle'):
          with open('token_drive.pickle', 'rb') as token_drive:
               creds = pickle.load(token_drive)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
   if creds and creds.expired and creds.refresh_token:
           creds.refresh(Request())
   else:
      flow = InstalledAppFlow.from_client_secrets_file(
     Credentials_drive.json', 'https://www.googleapis.com/auth/drive.metadata.readonly')
      creds1 = flow.run_local_server(port=0)
      # Save the credentials for the next run
      with open('token_drive.pickle', 'wb') as token_drive:
           pickle.dump(creds, token_drive)

   drive_service= build('drive', 'v3', credentials=creds1)


sleep(5)
    

# for gmail api---------------------------------------------------------------------------------   
# If modifying these scopes, delete the file token.pickle.



creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.

if os.path.exists('token.pickle'):
            with open('token.pickle', 'rb') as token:
                 creds = pickle.load(token)
        
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
               creds.refresh(Request())
    else:
       flow = InstalledAppFlow.from_client_secrets_file(
      'Credentials.json', 'https://www.googleapis.com/auth/gmail.readonly')
       creds = flow.run_local_server(port=0)
       # Save the credentials for the next run
       with open('token.pickle', 'wb') as token:
             pickle.dump(creds, token)
            
    service = build('gmail', 'v1', credentials=creds)




# Call the Gmail API
results = service.users().labels().list(userId='me').execute()

#Get Messages

results = service.users().messages().list(userId='me',q=q, maxResults=maxResults ,labelIds=['INBOX']).execute()
messages = results.get('messages', [])


def create_folder_in_drive(service,folder_name,parent_folder=[]):
    file_metadata ={
        
        'name':    folder_name,
        'parents': parent_folder,
        'mimeType':'application/vnd.google-apps.folder' 
        
        }      



for  message in messages:
            msg = service.users().messages().get(userId='me',metadataHeaders=['parts'], id=message['id']).execute()
            messageID=msg['threadId']
            messageSubject='(No Subject)({0})'.format(messageID)
            msgdetail=msg.get('payload')
          
            for item in msgdetail['headers']:
                if item['name']=='Subject':
                   if item['value']:
                       messageSubject='{0} ({1})'.format(item['value'],messageID)
                   else:
                       messageSubject='(No Subject)({0})'.format(messageID)
            print("messagesubject:" ,  messageSubject    )
            
            
            #create drive folder
            folder_id=create_folder_in_drive(drive_service,messageSubject)
            
            if 'parts' in msgdetail:
                
                for msgPayload in msgdetail['parts']:
                    mime_type=msgPayload['mimeType'] 
                    file_name=msgPayload['filename']
                    body=msgPayload['body']
                    print(body)
                    if 'attachmentId' in body:
                        attachment_id=body['attachmentId']
                        response=service.users().messages().attachments().get(
                            userId='me',
                            messageId=msg['id'],
                            id=attachment_id
                        ).execute()
                        
                        file_data=base64.urlsafe_b64decode(
                             response.get('data').encode('UTF-8'))
                                            
                        fh=io.BytesIO(file_data)
                        
                        file_metadata= {
                          'name':file_name,
                          'parents':[folder_id]
                            
                        }
                        
                        media_body=MediaIoBaseUpload(fh,mimetype=mime_type,chunksize=1024*1024,resumable=True)
                        
                        file=drive_service.files().create(
                          body=  file_metadata,
                          media_body=media_body,
                          fields='id'
                            
                            ).execute()

朋友们大家好,如果我删除文件目录中的token.pickle和token_drive.pickle文件(这些文件是与google cloud分开创建的)并运行代码:

”ResumableUploadError:

这似乎是Gmail和Drive同时身份验证的问题,因为media\u body和file\u元数据返回一个值,但我无法解决这个问题。

共有2个答案

穆歌者
2023-03-14

#for gmail and drive api------------------------------------------------------------

# If modifying these scopes, delete the file token.pickle.
SCOPES=['https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.file','https://www.googleapis.com/auth/drive.metadata']


creds = None
# The file token.pickle stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.

if os.path.exists('token.pickle'):
    with open('token.pickle', 'rb') as token:
         creds = pickle.load(token)

# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
       creds.refresh(Request())
    else:
       flow = InstalledAppFlow.from_client_secrets_file(
      'Credentials.json', SCOPES)
       creds = flow.run_local_server(port=0)
       # Save the credentials for the next run
       with open('token.pickle', 'wb') as token:
             pickle.dump(creds, token)
    
service = build('gmail', 'v1', credentials=creds)
drive_service = build('drive', 'v3', credentials=creds)
    
柯正谊
2023-03-14

我在打电话,盯着你的代码。

您应该能够获得一个范围足以支持Gmail和Drive的令牌,而不是篡改多个令牌。

取消拾取对象也可能会导致某种碰撞。尽管这只适合你,我还是建议你尽量避免酸洗。

这里有一个Google示例,显示了使用Python的Gmail的OAuth流。该示例将|读取令牌作为文件写入磁盘。使用这两个作用域尝试此代码。

 类似资料:
  • 我已经使用zappa在aws lambda上部署了一个flask应用程序,现在该应用程序在所有endpoint上都运行良好,除了我的主endpoint,当我对其发出post请求时,它返回{“消息”:“endpoint请求超时”} 真的需要一个修复或想法如何克服这个我需要调用分析路线,部署的url是 https://2ixfyfcsik.execute-api.eu-west-2.amazonaws

  • 我一直在尝试实现运行时权限。下面是它的代码片段: RunTimePermissionsUtil。JAVA 在一个名为AddFileActivity的活动中,我在一个点击事件中实现了这个监听器,其代码如下: 所以,我所有的代码都会执行,它会进入onNeed权限()代码,其中,它会进入 但是,令人惊讶的是,在此之后,没有任何对话框要求获得摄像头的运行时权限,相反,对话框关闭并再次显示活动。 有没有人能

  • 我正在为一个iOS应用程序构建一个Rails后端。后端需要与脸谱网接口,以获取和使用每个用户的脸谱网朋友。 但脸书的“朋友”请求却是空的。 我基本上提出了以下要求: 我看过大量关于StackOverflow的帖子(这个、这个、这个等等),但没有找到一个相同的问题或适合的解决方案。 我似乎设置了正确的权限。无论是在Rails应用上还是当用户通过iPhone应用进行身份验证时,我都将< code>us

  • 实际错误消息: 未处理的异常:Google。谷歌例外:谷歌。API。请求。RequestError权限不足[403]错误[消息[权限不足]位置[-]原因[权限不足]域[全局]] 它只在我尝试访问组时抛出此错误。我可以很好地获得用户。这是我的代码: 调用IList时引发错误 我错过了什么吗?我尝试包含持有的所有范围,但仍然收到相同的错误。 有人有什么意见吗?

  • HttpURLConnection使我的应用程序崩溃,因为即使我在清单文件中使用标记,也没有授予internet权限

  • 首先,我知道这是一个重复的问题,但我已经看过了其他类似问题的答案,没有找到成功的解决方案。 我已经开发了一款应用程序,可以在我的测试设备上完美运行,这是一款运行Android L(5.0.1)的三星S4。不过,我希望这款应用程序也能在较新版本的Android上运行。 我知道Android M的请求权限已更改,因此必须在运行时请求权限,但当我尝试实现此功能时,对话框从未出现,因此从未请求所需的权限。