React前端+Python后端如何通过用户授权访问Google Drive并上传文件?
Hey there! Let's figure out how to get your Python backend connected to Google Drive and upload files successfully, since the token data your React frontend has right now isn't sufficient for full Drive API operations.
Why your current token data isn't enough
The data your frontend received is just basic info about an access token—it's short-lived (only ~1 hour here) and lacks critical fields like a refresh_token (which lets you get a new access token without re-authenticating the user) and proper context for the backend to authenticate with Google's API properly.
Solution 1: Use the Authorization Code Flow (User-Specific Uploads)
This is the right approach if you need to upload files on behalf of the authenticated user. Here's how to adjust your flow:
Step 1: Update your React frontend's authorization request
Instead of requesting an access token directly, configure your Google OAuth request to return an authorization code instead. Make sure to set:
access_type: 'offline'(so Google issues a refresh token)response_type: 'code'
Once the user authorizes, your frontend will get an authorization code—send this code to your Python backend, not just the access token data.
Step 2: Backend code to exchange the code for full credentials
Use the google-api-python-client library to swap the authorization code for a complete set of OAuth2 credentials (including access token, refresh token, and expiration details).
First install the required packages:
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
Then implement the code:
from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import Flow from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload import os # Store these in environment variables—never hardcode them! CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID") CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET") REDIRECT_URI = os.getenv("GOOGLE_REDIRECT_URI") # Match your React app's redirect URI def exchange_auth_code(auth_code): # Set up the OAuth flow flow = Flow.from_client_config( { "web": { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "redirect_uri": REDIRECT_URI, "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", } }, scopes=["https://www.googleapis.com/auth/drive"], ) flow.redirect_uri = REDIRECT_URI # Exchange code for credentials credentials = flow.fetch_token(code=auth_code) return credentials def upload_file_to_drive(credentials, file_path, target_folder_id=None): # Build the Drive service creds = Credentials.from_authorized_user_info(credentials) drive_service = build("drive", "v3", credentials=creds) # Define file metadata file_metadata = {"name": os.path.basename(file_path)} if target_folder_id: file_metadata["parents"] = [target_folder_id] # Prepare the file for upload media = MediaFileUpload(file_path, resumable=True) # Execute the upload uploaded_file = drive_service.files().create( body=file_metadata, media_body=media, fields="id" ).execute() print(f"File uploaded successfully! ID: {uploaded_file['id']}") return uploaded_file["id"] # Example usage: # auth_code = request.json.get("auth_code") # Get code from frontend request # credentials = exchange_auth_code(auth_code) # upload_file_to_drive(credentials, "/path/to/your/local/file.jpg")
Key notes here:
- Store your client ID/secret in environment variables for security.
- The
credentialsobject will include arefresh_token—you can save this in your database to reuse it later, so the user doesn't have to re-authenticate every hour.
Solution 2: Use a Service Account (Backend-Automated Uploads)
If you don't need to upload files on behalf of individual users (e.g., backend batch jobs), a service account is a better fit. It lets your backend authenticate directly with Google Drive without user interaction.
Step 1: Set up the service account
- Go to the Google Cloud Console, create a service account, and download its JSON key file.
- Share the target Drive folder (or files) with the service account's email address (found in the JSON key).
Step 2: Backend code for service account uploads
from google.oauth2.service_account import Credentials from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload import os SCOPES = ["https://www.googleapis.com/auth/drive"] SERVICE_ACCOUNT_KEY_PATH = os.getenv("GOOGLE_SERVICE_ACCOUNT_KEY_PATH") def upload_with_service_account(file_path, target_folder_id=None): # Load service account credentials creds = Credentials.from_service_account_file( SERVICE_ACCOUNT_KEY_PATH, scopes=SCOPES ) # Build Drive service drive_service = build("drive", "v3", credentials=creds) # File metadata file_metadata = {"name": os.path.basename(file_path)} if target_folder_id: file_metadata["parents"] = [target_folder_id] # Upload media media = MediaFileUpload(file_path, resumable=True) uploaded_file = drive_service.files().create( body=file_metadata, media_body=media, fields="id" ).execute() print(f"File uploaded! ID: {uploaded_file['id']}") return uploaded_file["id"] # Example usage: # upload_with_service_account("/path/to/your/file.pdf", "your-drive-folder-id")
Which solution should you choose?
- Authorization Code Flow: Use this when you need to act on behalf of a specific authenticated user (e.g., the user uploads their own file to their Drive).
- Service Account: Use this for backend-only tasks where no user interaction is needed (e.g., uploading backup files to a shared Drive folder).
内容的提问来源于stack exchange,提问作者r4v1

