如何动态通过邮箱密码获取谷歌日历事件?应用中如何借助服务账户调用Calendar API
Hey there! Let's tackle your two questions clearly—these are common scenarios when working with the Google Calendar API, so I'll break things down in a way that's actionable for your app.
Short answer: No, and you shouldn’t even try this.
Google long ago deprecated the OAuth 2.0 Password Grant type for all its APIs, including Calendar. This method is inherently risky—storing or transmitting user passwords puts both your users and your app at risk of data breaches. Worse, it violates Google’s Service Terms, which could lead to your app being blocked from accessing Google services entirely.
Any workaround that tries to simulate password-based login (like scraping the Google login page) is also against Google’s policies and will break as soon as Google updates its authentication flow. So forget about passing email/password directly—there’s no supported or safe way to do this.
Your scenario makes sense: users have their own accounts in your app, and you need to access their Google Calendar via a service account. The approach depends on whether your users are on Google Workspace (formerly G Suite) or regular Gmail accounts:
Option 1: For Google Workspace users (domain-managed accounts)
If your users belong to a Google Workspace domain, you can use Domain-Wide Delegation to let your service account impersonate any user in the domain. Here’s how to set it up:
- In the Google Cloud Console, create a service account and download its JSON key file.
- Enable Domain-Wide Delegation for the service account, then add the necessary Calendar API scopes (e.g.,
https://www.googleapis.com/auth/calendar.readonlyfor read access). - Log into your Google Workspace Admin Console, navigate to Security > API Controls > Domain-wide delegation, and authorize your service account’s client ID to use the scopes you added.
Once set up, you can impersonate the user directly in code (no manual authorization needed from the user):
from google.oauth2 import service_account from googleapiclient.discovery import build # Path to your service account key file SERVICE_ACCOUNT_KEY = "path/to/your-service-account.json" # The user's email you want to access USER_EMAIL = "user@your-workspace-domain.com" # Calendar API scopes (adjust based on your needs) SCOPES = ["https://www.googleapis.com/auth/calendar.readonly"] # Create credentials by impersonating the user credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_KEY, scopes=SCOPES, subject=USER_EMAIL ) # Build the Calendar API service service = build("calendar", "v3", credentials=credentials) # Fetch upcoming events from the user's primary calendar events = service.events().list(calendarId="primary", maxResults=10).execute() for event in events.get("items", []): start_time = event["start"].get("dateTime", event["start"].get("date")) print(f"{start_time}: {event['summary']}")
Option 2: For regular Gmail users
Domain-wide delegation doesn’t work for regular Gmail accounts. Instead, you have two valid options:
- User-shared calendars: Ask the user to share their calendar with your service account’s email address (found in the service account JSON key). They can set permissions like "View all events" in Google Calendar’s sharing settings. Your service account can then access the calendar directly using its own credentials.
- OAuth 2.0 Authorization Flow: This is the better user experience. Redirect the user to Google’s OAuth consent screen, where they grant your app permission to access their Calendar. Your app will receive an access token (and refresh token) that you can store securely. Later, you can use these tokens to call the Calendar API on their behalf—no service account required, though you can still use one to manage token storage if needed.
Critical Notes:
- Never ask users for their Gmail password—this is a huge security red flag and violates Google’s policies.
- Always use the least-privilege scopes possible (e.g.,
readonlyinstead of full access) to minimize risk if credentials are compromised. - Store refresh tokens securely (encrypted, not plaintext) since they can be used to access the user’s data indefinitely until revoked.
内容的提问来源于stack exchange,提问作者Kumar Elubandi

