oauth2
Einleitung
Diese Seite entstand - nach Umstieg auf ein Android Smartphone - als ich nichts zur Todolistenverwaltung gefunden habe. Zumindest keine Lösung mit nativen Anwendungen
-
am Windows Desktop (Arbeit)
-
am Ubuntu Laptop (auf der Couch)
-
und auf den Telefon (Android)
Mein angedachter Workaround:
-
eine bestehende Android App verwenden (gTasks), die Google Tasks als Cloud Speicher nutzt.
-
Dazu dann eine rudimentäre Java SWT Anwendung für PC und Laptop erstellen.
der Widerstand
Google bietet eine Java API für den Zugriff auf die Tasks an (derzeit in BETA, Stand Januar 2013). Ein Downloadlink findet sich am Ende der Seite.
Der meiste Code/Forschungsaufwand geht eigentlich für die OAUTH2 Authentifizierung (Anmeldung) drauf.
OAUTH2 und Google Tasks
Ab hier wird der Weg zu einer funktionierenden Tasks Abfrage mit Java skizziert.
Der gezeigte Code ist aus meinen Unit Tests entnommen. Er erhält damit keinen Schönheitspreis, ist aber (derzeit) lauffähig.
die eigene Anwendung bei Google registrieren
Dieser Step ist nur einmalig für eine Anwendung zu durchlaufen.
Man registiert seine neue Anwendung, und schaltet für sie die Tasks API zur Nutzung frei. Von Google gibts dann ClientID und Client Secret für genau diese Anwendung. Das alles macht man bequem im Browser bei Google.
-
mit der Google Kennung (your.google.mail.id@gmail.com) des Programmierers anmelden
-
die Anwendung einrichten
-
mit "create project" die eigene Anwendung bei Google bekanntmachen
-
-
die Anwendung soll Zugriff auf die Tasks API bekommen
-
Der Anwendung das Login mit OAUTH2 ermöglichen
-
API Access
-
Create an OAuth 2.0 client ID
-
-
Ich baue hier einen "Fat Client", d aher also "Installed Application" wählen
Note
|
merken der ClientID, braucht man später im Code: *.apps.googleusercontent.com |
Note
|
ebenfalls das Client Secrect merken: u0*lb6 |
AuthorizationCodeFlow der Google API ansprechen
Jetzt geht es in den Java Code. Beim Login dreht sich alles um die AuthorizationCodeFlow Klasse. Die wird hier erst einmal initialisiert.
-
fuer die Anwendung (ClientID / Client Secret)
-
für Task Zugriffe auf den Google User Account "userGoogleAccount"
-
Userdaten werden in der Datei "MyAppsDemoCredentialStore.json" aufbewahrt
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new GsonFactory();
String GOOGLE_OAUTH2_TOKEN_URI = "https://accounts.google.com/o/oauth2/token"; // google server für oauth2 tokens
String GOOGLE_OAUTH2_AUTH_URI = "https://accounts.google.com/o/oauth2/auth"; // google server für oauth2
// Ablage der Zugänge Appuser im Dateisystem..
FileCredentialStore credentialStore = new FileCredentialStore(new File("MyAppsDemoCredentialStore.json"), jsonFactory);
// Initialisieren OAuth2 flow
AuthorizationCodeFlow authorizationCodeFlow = new AuthorizationCodeFlow.Builder(BearerToken.authorizationHeaderAccessMethod(), httpTransport,
jsonFactory, new GenericUrl(GOOGLE_OAUTH2_TOKEN_URI),
new ClientParametersAuthentication(
"****.apps.googleusercontent.com", // CLIENT Id (bleibt konstant für diese Anwendung)
"u0*************b6"), // CLIENT Secret (bleibt konstant für diese Anwendung)
"****.apps.googleusercontent.com", GOOGLE_OAUTH2_AUTH_URI)
.setCredentialStore(credentialStore)
.setScopes(Arrays.asList("https://www.googleapis.com/auth/tasks")) // anzufordernde Rechte (Hier: Zugriff auf google tasks)
.build();
assertNotNull(authorizationCodeFlow);
// Zugangscredentials bereits in credentialStore abgelegt (Folgeaufruf ?)
Credential storedUserCredential = authorizationCodeFlow.loadCredential(userGoogleAccount);
assertNull(storedUserCredential); // das soll hier der erste Aufruf sein.
Damit hat man mal die Verbindung vorbereitet, Die Datei mit den User Credentials ist leer angelegt.
Anwendung den Zugriff auf Tasks eines Users erlauben
Dieser Codeteil muss für jeden neuen User durchlaufen werden.
Zugriff erteilt der jeweilige User im Browser. Seine Credentials werden lokal abgespeichert für spätere Verwendung durch die Anwendung.
// URL erstellen, damit kann der User dann gleich im Browser den Zugriff dieser Anwendung
// auf die Tasks in seinem google Account erlauben..
AuthorizationCodeRequestUrl authorizationUrl = getAuthorizationCodeFlow().newAuthorizationUrl();
authorizationUrl.setRedirectUri("urn:ietf:wg:oauth:2.0:oob");
String authorizationUrlString = authorizationUrl.build();
// URL im Web Browser öffnen ...
System.out.println("Attempting to open a web browser to start the OAuth2 flow");
openBrowser(URI.create(authorizationUrlString));
// nun muss der User den angezeigten Code übernehmen in die App:
System.out.print("Den angezeigten Code bitte hier kopieren: ");
String code = new Scanner(System.in).nextLine();
// und jetzt wird die Zugriffserlaubnis für diesen User auf der Festplatte permanent abgespeichert
TokenResponse response = authorizationCodeFlow.newTokenRequest(code).setRedirectUri("urn:ietf:wg:oauth:2.0:oob").execute();
authorizationCodeFlow.createAndStoreCredential(response, userGoogleAccount);
Im Browser gibt der User die Zugriff auf seine Tasks frei
Dafür gibt es einen Bestätigungscode von Google, den kopiert der User aus dem Browser.
Den Code muss der Anwendung wieder mitgeteilt werden
Diese generiert damit ein Token und speichert es lokal (hier im json Format) im Dateisystem ab.
Login bei Google
Bei jedem Anwendungsstart muss der jeweilige User bei Google angemeldet werden, die Credentials dazu wurden im Step zuvor lokal gespeichert.
Credential storedUserCredential = authorizationCodeFlow.loadCredential(userGoogleAccount); // use XXXXX@gmail.com Account
assertNotNull(storedUserCredential);
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new GsonFactory();
Tasks tasksService = new Tasks(httpTransport, jsonFactory, storedUserCredential);
assertNotNull(tasksService);
Abfrage Tasks
So bei Google angemeldet kann man von dort die Tasks zum User Account auslesen.
Dazu nutzt man die Google API Java Library als Wrapper über die eigentlichen REST Aufrufe gegen die Google Server.
// Tasklisten abfragen ..
TaskLists returnedLists = tasksService.tasklists().list().execute();
for(TaskList list : returnedLists.getItems() )
{
System.out.println("* " + list.getId() + "/" + list.getTitle() + "/" + list.getEtag());
// Tasks in aktueller Taskliste abfragen..
com.google.api.services.tasks.Tasks.TasksOperations.List execTasks = tasksService.tasks().list(list.getId());
execTasks.setShowCompleted(false);
execTasks.setShowDeleted(false);
com.google.api.services.tasks.model.Tasks tasks = execTasks.execute();
if( tasks != null && ! tasks.isEmpty() && tasks.getItems() != null)
{
for(Task t : tasks.getItems())
{
System.out.println(" - " + t.getId() + "/" + t.getTitle() + "/" + t.getStatus() + "/"
+ t.getDue() + "/ [" + t.getNotes() + "]");
}
}
}
Am Ziel, der Code gibt die aktuellen Tasklisten inclusive deren Einträge aus:
Referenzen
-
Google Tasks API,
-
siehe https://developers.google.com/google-apps/tasks/ mit Stand 1.12.0 beta
-
OAUTH2 mit der Google API: http://javadoc.google-oauth-java-client.goolecode.com/hg/1.12.0-beta/com/google/api/client/auth/oauth2/AuthorizationCodeFlow.html
-
-
OAUTH2 Spec http://datatracker.ietf.org/wg/oauth/
-
Eclipse IDE (Juno), http://www.eclipse.org
-
Java JDK 1.7, http://www.oracle.com/technetwork/java
-
Dieses Dokument wurde erstellt mit asciidoc 8.6.7, siehe http://www.methods.co.nz/asciidoc/
-
Fixing Source Highlighting für asciidoc unter Windows http://www.valvers.com/programming/asciidoc-for-project-documentation
-
Homepage des Dokuments https://www.regele.org