Google Drive服务账号认证时遇到googleapiclient.errors.HttpError: 401 "请求缺少所需认证凭证

0 投票
0 回答
28 浏览
提问于 2025-04-11 22:40

我正在写一个小应用程序,用来通过服务账号把文件上传到共享的Google Drive。这个服务账号是通过一个JSON文件来认证的,不需要用户的授权或同意,服务账号也已经直接获得了权限。网上有很多示例脚本,但没有一个能直接用。最后我写出了下面这个脚本。我之前能连接几次并从Drive读取文件,但后来我休息了一下。等我回来时,开始出现了一些错误:

"[{'message': 'Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.', 'domain': 'global', 'reason': 'unauthorized'}]

当前的代码(加了一些额外的行来强制流量进入Fiddler进行检查)是:

from google.oauth2 import service_account
from googleapiclient.discovery import build
import google.auth.transport.requests
import httplib2
import google_auth_httplib2

import os, sys, argparse
import json
from pprint import pprint

parser=argparse.ArgumentParser()
parser.add_argument("--keyfile", help="JSON key file",required=True)
parser.add_argument("--datafile", help="File to upload",required=True)
parser.add_argument("--folderid", help="Google Drive folder for the file",required=True)
args=parser.parse_args()

def upload_file_to_gdrive(key_file,folder_id,data_file):
    
    print(os.path.abspath(key_file))
    #scopes = ['https://www.googleapis.com/auth/drive.metadata', 'https://www.googleapis.com/auth/drive']
    scopes = ['https://www.googleapis.com/auth/drive']
    
    creds = service_account.Credentials.from_service_account_file(filename=key_file,scopes=scopes)
    # if not creds or not creds.token_state:
    #     if creds and creds.expired and creds.refresh_token:
    creds.refresh(google.auth.transport.requests.Request())

    print(creds.service_account_email)
    print(creds.valid)
    print(creds.token_state)

    http = httplib2.Http(disable_ssl_certificate_validation=True ,
                         proxy_info=httplib2.ProxyInfo(httplib2.socks.PROXY_TYPE_HTTP, "localhost", 8888 ) )
    authorized_http = google_auth_httplib2.AuthorizedHttp(credentials=creds, http=http)
    service = build(serviceName='drive',version='v3', http=authorized_http)

    #service = build(serviceName='drive',version='v3',credentials=creds)
    
    results = service.about().get(fields="*").execute()  

upload_file_to_gdrive(args.keyfile,args.folderid,args.datafile)

通过Fiddler,我可以看到客户端正在访问令牌API,地址是 https://oauth2.googleapis.com/token,并且收到了一个访问令牌。我还看到这个访问令牌被包含在请求中,用来获取 https://www.googleapis.com/drive/v3/about 的信息。

GET https://www.googleapis.com/drive/v3/about?fields=%2A&alt=json HTTP/1.1
Host: www.googleapis.com
accept: application/json
accept-encoding: gzip, deflate
user-agent: (gzip)
x-goog-api-client: gdcl/2.124.0 gl-python/3.12.2 cred-type/sa
content-length: 0
authorization: Bearer ya29.c.c0AY_VpZgZ-JOjiMEHpXd5JDFydx33qiEjyGA8k52SGhRmZqPVaXIo8lEhY2gkHt8VmtGrD8H0qWkIkkKk.....

是什么原因导致这个访问令牌被服务拒绝呢?

0 个回答

暂无回答

撰写回答