'Gdrive API returns data from wrong drive
I'm using code below to connect to gdrive service and get data from drive, as far as I am concerned with cliend_id and client_secret given I literally choose which drive I wanna connect to, however when authentication window pop-up there is i.e. Account A where my target drive is and Account B which i gave a share to Account A, if i choose Account A as authentication everything works well, but with Account B it's connecting to Account B's drive. My goal is to always connect to Account A's drive.
#via OAuth 2.0 token
def get_gdrive_service_v2(project_name):
status = ""
scopes = ['https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/drive.appdata',
'https://www.googleapis.com/auth/drive.file',
'https://www.googleapis.com/auth/drive.metadata',
'https://www.googleapis.com/auth/drive.metadata.readonly',
'https://www.googleapis.com/auth/drive.photos.readonly',
'https://www.googleapis.com/auth/drive.readonly']
#insert credentials json file content here
creds_local = {}
if project_name == "stage":
creds_local = {"installed": {"client_id": "xxx",
"project_id": "xxx", "auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "{client_secret}".format(client_secret = os.environ.get("GDRIVE_STAGE_SECRET")), #not in code
"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]}}
flow = InstalledAppFlow.from_client_config(creds_local, scopes)
creds = flow.run_local_server(port=0)
status = "Everything good, google drive connected"
return build('drive', 'v3', credentials=creds), status
Solution 1:[1]
cliend_id and client_secret given I literally choose which drive I wanna connect to.
The client id and client secret identity your application to Google. That is all it has no relation to which account you connect to.
When you run your code the application will request authorization of a user. The user to access their data. A refresh token and an access token are returned.
Normally the developer would store this token token for later use. In the code below it is being stored in Token.json file. This code would only work for a single user as as long as the file exits it will be loaded from there.
if os.path.exists('token.json'):
creds = Credentials.from_authorized_user_file('token.json', SCOPES)
# 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.json', 'w') as token:
token.write(creds.to_json())
Service accounts
I think you should consider looking into serice account authorization instead of installed application authorization.
If you create a service account and then share a directory on Account A the service account will have access to account A until you remove said access. Your code would then always be accessing that account.
scope = ['https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name('creds.json' % path, scope)
service = build('drive', 'v3', credentials=credentials)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | DaImTo |
