Oauth2用于google API访问似乎依赖于请求Python任务的用户id



我正在重写一个程序,需要发送和接收电子邮件的能力。旧版本在桌面上独立运行,使用SMTP和POP3以我的名义使用gmail帐户发送和接收。这还好,但是,最近,很多发送的邮件最后都被扔进了垃圾文件夹。所以,我希望有一种更可靠的方式来代表我发送。用户(我)。新版本是一个网络应用程序,而不是桌面程序,所以电子邮件活动是在服务器端完成的,我正在尝试使用Gmail的API。

当进程在服务器上运行时,我已经被卡住了几天,无法获得API访问令牌(无效令牌)。我是这样做的:

  1. 使用Google云平台控制台创建/下载凭据。json文件
  2. 使用"快速开始"成功测试用户授权的Python代码,将令牌保存为文件令牌。并发送测试消息
  3. 将类似的代码合并到我的程序中,但从命令行将其作为测试运行>成功!
  4. 将整个文件夹复制到我的服务器上,并使用SSH终端,从命令行再次运行它作为测试>成功(包括使用Refresh令牌)!
  5. 将其作为web应用程序(WSGI Python)运行,它失败了。

注意到任务的所有者不是我,当它作为web应用程序运行时,在SSH终端上,我将user更改为"www-data"然后重新尝试测试并击中错误(提示)。

后为valid == Falsecreds = Credentials.from_authorized_user_file('token.json', scopes=SCOPES)结果触发了用户身份验证流——这是它停止的地方,因为它不能远程使用(我相信)。

我已经确保文件夹中的所有文件对两个用户(www-data和ben)都可以平等地访问。谁能给我点提示,我该怎么做才能让"www-data"正常工作?用户吗?

def get_credentials():
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/gmail.readonly','https://www.googleapis.com/auth/gmail.send']
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
logging("In get_credentials. Python version: " + sys.version )
if os.path.exists('token.json'):
logging("Using token.json")
with open('token.json',"r",encoding="utf-8") as fi:
s = fi.read()
logging( s )
logging( str(os.environ))
creds = Credentials.from_authorized_user_file('token.json', scopes=SCOPES)
logging("Creds " + str(creds))
logging(str(creds.refresh_token) + " " + str( creds.expired) + " " + str( creds.valid))

# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
logging("No valid credentials found")
if creds and creds.expired and creds.refresh_token:
logging("Going for a refresh")
creds.refresh(Request())
else:
logging("Going for live authentication flow!")
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.json', 'w') as token:
token.write(creds.to_json())
logging("Saved token.json")
service = build('gmail', 'v1', credentials=creds)

return service

您正在使用的问题是您的InstalledAppFlow。这将导致在运行代码的机器上弹出同意屏幕,然后将刷新令牌和访问令牌存储在token.json中。

您可以做的是在本地运行一次以确保令牌。创建Json,然后确保在将其上传到服务器时使用令牌。Json也被上传。

请记住,除非您的应用程序被设置为生产,否则您的刷新令牌只会在七天内有效,因此您需要每周在本地重新授权一次。

最新更新