it-swarm.com.de

Automatisierung des Verifizierungsprozesses

Ich versuche, den GoogleAuth-Prozess zu automatisieren, wenn Sie die pydrive-Bibliothek verwenden ( https://pypi.python.org/pypi/PyDrive ).

Ich habe das pydrive und die google API so eingerichtet, dass mein secret_client.json funktioniert, es erfordert jedoch eine Webauthentifizierung für den Zugriff auf gdrive bei jeder Ausführung meines Skripts:

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
gauth.LocalWebserverAuth()

drive = GoogleDrive(gauth)

textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile

drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')

eng.txt ist nur eine Textdatei. Außerdem, wenn ich versuche, das obige Skript zu verwenden, während ich bei einem anderen Konto angemeldet bin. Es lädt nicht den eng.txt in mein Laufwerk hoch, der den secret_client.json generiert hat, sondern das Konto, das bei der Autorisierung der Authentifizierung angemeldet war.

Im vorherigen Beitrag habe ich Folgendes versucht, um den Überprüfungsprozess zu automatisieren, es werden jedoch Fehlermeldungen angezeigt: 

import base64, httplib2
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

from apiclient.discovery import build
from oauth2client.client import SignedJwtAssertionCredentials
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

#gauth = GoogleAuth()
#gauth.LocalWebserverAuth()

# from google API console - convert private key to base64 or load from file
id = "464269119984-j3oh4aj7pd80mjae2sghnua3thaigugu.apps.googleusercontent.com"
key = base64.b64decode('COaV9QUlO1OdqtjMiUS6xEI8')

credentials = SignedJwtAssertionCredentials(id, key, scope='https://www.googleapis.com/auth/drive')
credentials.authorize(httplib2.Http())

gauth = GoogleAuth()
gauth.credentials = credentials

drive = GoogleDrive(gauth)

drive = GoogleDrive(gauth)

textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile

drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')

Error:

Traceback (most recent call last):
  File "/home/alvas/git/SeedLing/cloudwiki.py", line 29, in <module>
    textfile.Upload()
  File "/usr/local/lib/python2.7/dist-packages/pydrive/files.py", line 216, in Upload
    self._FilesInsert(param=param)
  File "/usr/local/lib/python2.7/dist-packages/pydrive/auth.py", line 53, in _decorated
    self.auth.Authorize()
  File "/usr/local/lib/python2.7/dist-packages/pydrive/auth.py", line 422, in Authorize
    self.service = build('drive', 'v2', http=self.http)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/apiclient/discovery.py", line 192, in build
    resp, content = http.request(requested_url)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/util.py", line 132, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 475, in new_request
    self._refresh(request_orig)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 653, in _refresh
    self._do_refresh_request(http_request)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 677, in _do_refresh_request
    body = self._generate_refresh_request_body()
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 861, in _generate_refresh_request_body
    assertion = self._generate_assertion()
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 977, in _generate_assertion
    private_key, self.private_key_password), payload)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/crypt.py", line 131, in from_string
    pkey = crypto.load_pkcs12(key, password).get_privatekey()
OpenSSL.crypto.Error: [('asn1 encoding routines', 'ASN1_get_object', 'header too long')]

Meine Authentifizierung auf gdrive api sieht folgendermaßen aus:

enter image description here

Wie kann ich pydrive so verwenden, dass ich mich nicht jedes Mal authentifizieren muss, wenn ich es benutze?

Wie kann eine automatische Authentifizierung zugelassen werden, sodass das Python-Skript, das das Pydrive-Skript verwendet, nur auf das Konto hochgeladen wird, das den secret_client.json generiert hat, und nicht das aktuell angemeldete Konto im Internetbrowser?

40
alvas

Zuerst missverstehen Sie ein sehr wichtiges Stück, wie das funktioniert:

wenn ich versuche, das obige Skript zu verwenden, während ich bei einem anderen .__ angemeldet bin. Konto. Die eng.txt wird nicht in mein gdrive hochgeladen, das .__ generiert hat. das secret_client.json aber das Konto, das angemeldet war, als ich Autorisieren Sie die Authentifizierung

Genau so soll es funktionieren. Sie als Entwickler verteilen client_secret.json mit Ihrer Anwendung, und diese Datei wird von PyDrive verwendet, um die Anwendung bei Google zu authentifizieren. Google möchte wissen, wie viele API-Anforderungen jede Anwendung aus verschiedenen Gründen anfordert (Metriken, Belastung des Kontos, Zugriff widerrufen usw.). Daher muss sich die Anwendung authentifizieren. 

Wenn Ihre Anwendung LocalWebserverAuth ausführt, wird der client jetzt bei Google authentifiziert. Der Kunde ist natürlich die Person, die Ihre Anwendung tatsächlich verwendet. In diesem Fall sind der Entwickler und der Kunde dieselbe Person (Sie). Sie können sich jedoch vorstellen, dass Sie Ihre Anwendung an eine Million verschiedene Personen verteilen möchten. Sie müssen in der Lage sein, sich zu authentifizieren und Dateien in ihr eigenes Drive-Konto hochzuladen, anstatt sie alle in Ihrem (dem Entwickler) zu enden, der client_secret.json angegeben hat.

Das heißt, es ist wirklich nur eine sehr geringfügige Änderung, um es so zu machen, dass Ihre App den Client nicht bei jeder Ausführung der App zur Authentifizierung auffordern muss. Sie müssen nur LoadCredentialsFile und SaveCredentialsFile verwenden.

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive

gauth = GoogleAuth()
# Try to load saved client credentials
gauth.LoadCredentialsFile("mycreds.txt")
if gauth.credentials is None:
    # Authenticate if they're not there
    gauth.LocalWebserverAuth()
Elif gauth.access_token_expired:
    # Refresh them if expired
    gauth.Refresh()
else:
    # Initialize the saved creds
    gauth.Authorize()
# Save the current credentials to a file
gauth.SaveCredentialsFile("mycreds.txt")

drive = GoogleDrive(gauth)

textfile = drive.CreateFile()
textfile.SetContentFile('eng.txt')
textfile.Upload()
print textfile

drive.CreateFile({'id':textfile['id']}).GetContentFile('eng-dl.txt')
72
dano

Alternativ können Sie einen benutzerdefinierten Authentifizierungsfluss verwenden, indem Sie die Datei setting.yaml in das Arbeitsverzeichnis schreiben. Und diese Methode funktioniert besser, da LocalWebserverAuth() ein Token generiert, das in nur einer Stunde abläuft und es kein Aktualisierungstoken gibt.

Ein Beispiel für die Datei settings.yaml sieht folgendermaßen aus

client_config_backend: file
client_config:
    client_id: <your_client_id>
    client_secret: <your_secret>

save_credentials: True
save_credentials_backend: file
save_credentials_file: credentials.json

get_refresh_token: True

oauth_scope:
    - https://www.googleapis.com/auth/drive
    - https://www.googleapis.com/auth/drive.install

Bei dieser Datei müssen Sie noch einen Browser verwenden, um die Authentifizierung zum ersten Mal abzuschließen, und anschließend wird eine credentials.json-Datei mit einem Aktualisierungstoken im Arbeitsverzeichnis generiert.

Diese Methode funktioniert besser, wenn Sie versuchen, Ihr Skript auf dem Server zu automatisieren

5
wang892

Dieser ganze Thread hat mir sehr geholfen, aber nachdem ich alle hier vorgestellten Lösungen implementiert hatte, trat ein weiteres Problem auf: LocalWebserverAuth () wird das Aktualisierungstoken nicht erhalten.

Wenn Sie die "mycreds.txt" öffnen, die nach der Implementierung von @ dano generiert wurde, wird das "Aktualisierungstoken" auf "null" gesetzt. Nach ein paar Stunden verfällt das Token und Sie erhalten Folgendes und müssen sich am Ende erneut manuell authentifizieren.

Der Fehler:

raise RefreshError('No refresh_token found.') pydrive.auth.RefreshError: No refresh_token found.Please set access_type of OAuth to offline.

Die Lösung hierfür besteht darin, die Eingabeaufforderung "approved_promt" zu erzwingen und "access_type" in den Ablaufparametern von GoogleAuth auf "offline" zu setzen.

So habe ich keine Fehler mehr bekommen:

gauth = GoogleAuth()

# Try to load saved client credentials
gauth.LoadCredentialsFile("mycreds.txt")

if gauth.credentials is None:
    # Authenticate if they're not there

    # This is what solved the issues:
    gauth.GetFlow()
    gauth.flow.params.update({'access_type': 'offline'})
    gauth.flow.params.update({'approval_Prompt': 'force'})

    gauth.LocalWebserverAuth()

Elif gauth.access_token_expired:

    # Refresh them if expired

    gauth.Refresh()
else:

    # Initialize the saved creds

    gauth.Authorize()

# Save the current credentials to a file
gauth.SaveCredentialsFile("mycreds.txt")  

drive = GoogleDrive(gauth)

Danke euch allen!

3
tetodenega

Wenn die Anmeldeinformationen nicht vorhanden sind, generiert dieser Code ein Eingabefeld mit zwei Optionen: 

  • Browser-Authentifizierung (die Sie nur einmal durchführen müssen)

  • Upload der Berechtigungsnachweisdatei (diese Datei wird zu der ersten Zeit generiert, die Sie für die Browser-Authentifizierung ausgewählt haben)

Nun ist es einfach, das Notebook gemeinsam zu nutzen, das einfach ohne Autorisierung ausgeführt werden kann, da es die in der mycreds.txt gespeicherten Anmeldeinformationen der lokalen Umgebung verwendet. Wenn die Laufzeit jedoch abstürzt oder zurückgesetzt wird, geht diese Datei verloren und muss erneut über das Eingabefeld oben eingefügt werden. Natürlich können Sie dies erneut über die Browser-Authentifizierung tun. Wenn Sie mycreds.txt jedoch an die Benutzer des Notebooks verteilen, können diese die Berechtigungsnachweise verwenden, um die Anmeldeinformationen in die lokale Umgebung einzufügen. 

Die letzten Zeilen enthalten nur ein Beispiel dafür, wie eine CSV-Datei vom authentifizierten Laufwerk hochgeladen und im Notebook verwendet werden kann. 

#Install the required packages and fix access to my Google drive account
!pip install pydrive
from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials


#Checks for file with Google authentication key, if the file is not in place, it asks to authenticate via the browser
gauth = GoogleAuth()
if os.path.isfile("mycreds.txt") is False:
    choice = input ("Do you want to: U) Upload authentication file (mycreds.txt). B) Browser authentication (only possible for owner of the connected Google drive folder). [U/B]? : ")
    if choice == "U":
          print ("Upload the mycreds.txt file")
          from google.colab import files
          files.upload()      
    Elif choice == "B":
          auth.authenticate_user()
          gauth.credentials = GoogleCredentials.get_application_default()
          gauth.SaveCredentialsFile("mycreds.txt")

gauth.LoadCredentialsFile("mycreds.txt")
if gauth.access_token_expired:
    gauth.Refresh()
else: gauth.Authorize()

#Now you can easily use the files from your drive by using their ID  
drive = GoogleDrive(gauth)
download = drive.CreateFile({'id': '1KRqYpR9cteX-ZIwhdfghju6_wALl4'})
download.GetContentFile('my_data.csv')
data_frame = pd.read_csv('my_data.csv')
0
Ger

Dies ist nur zum Abschluss von @ wang892 Beitrag oben (Ich habe nicht genug Ruf, um einen Kommentar abzugeben).

Diese Antwort hat mir dabei geholfen, mein Skript zu automatisieren (nicht bei jeder Ausführung erneut authentifizieren zu müssen).

Als ich jedoch die Beispieleinstell.yaml-Datei verfügbar in PyDrive-Dokumentation verwendet habe, bin ich auf Probleme gestoßen (aufgrund meiner völligen Unkenntnis darüber, wie Oauth funktioniert). 

Diese Beispieldatei enthält diese Zeilen, die meines Erachtens mein PyDrive-Skript auf den Zugriff auf nur von ihnen selbst erstellte Dateien und Ordner beschränkten (siehe PyDrive-Problem # 122 für Details):

Eingeschränkter Zugang:

oauth_scope:
  - https://www.googleapis.com/auth/drive.file
  - https://www.googleapis.com/auth/drive.install

Als ich diese Zeilen änderte, war das Problem gelöst (ich musste meine gespeicherten Anmeldeinformationen entfernen und das Skript ausführen, um es erneut zu autorisieren, nur noch einmal). 

Mit diesen neuen Zeilen hat mein Skript nun Zugriff auf alle Dateien in meinem Google Drive:

Voller Zugriff:

oauth_scope:
  - https://www.googleapis.com/auth/drive

Ein wenig mehr dazu in PyDrive Ausgabe # 108 , was mich sehr beleuchtet hat.

0
abu