Februar 2009
Einführung
„Wo finde ich Ruby in der Liste der Clientbibliotheken?“
Angesichts des unstillbaren Appetits unserer Entwickler und der anhaltenden Beliebtheit von Ruby on Rails (RoR) hat mein Kollege Jeff Fisher eine Ruby-Hilfsbibliothek aus den feurigen Tiefen des Schicksalsbergs geschmiedet. Es handelt sich nicht um eine vollständige Clientbibliothek, aber sie deckt die Grundlagen wie Authentifizierung und grundlegende XML-Bearbeitung ab. Außerdem müssen Sie direkt mit dem Atom-Feed arbeiten und dazu das REXML-Modul und XPath verwenden.
Zielgruppe
Dieser Artikel richtet sich an Entwickler, die mit Ruby, insbesondere Ruby on Rails, auf die Google Data APIs zugreifen möchten. Dabei wird davon ausgegangen, dass der Leser mit der Programmiersprache Ruby und dem Rails-Webentwicklungs-Framework vertraut ist. In den meisten Beispielen konzentriere ich mich auf die Documents List API, aber dieselben Konzepte können auf alle Data APIs angewendet werden.
Erste Schritte
Voraussetzungen
- Ruby 1.8.6, Patch-Level 114+ herunterladen
- RubyGems 1.3.1 oder höher herunterladen
- Rails 2.2.2+ herunterladen
Google Data Ruby Utility Library installieren
Sie können die Bibliothek entweder direkt aus dem Projekthosting herunterladen oder das Gem installieren:
sudo gem install gdata
Tipp: Führen Sie zur Sicherheit gem list --local
aus, um zu prüfen, ob das Gem richtig installiert wurde.
Authentifizierung
ClientLogin
Mit ClientLogin können sich Nutzer programmatisch in ihrer Anwendung in ihrem Google- oder G Suite-Konto anmelden. Nach der Validierung der Anmeldedaten des Nutzers gibt Google ein Authentifizierungstoken aus, auf das in nachfolgenden API-Anfragen verwiesen werden kann. Das Token bleibt für einen bestimmten Zeitraum gültig, der vom jeweiligen Google-Dienst abhängt, den Sie verwenden. Aus Sicherheitsgründen und um Ihren Nutzern die bestmögliche Erfahrung zu bieten, sollten Sie ClientLogin nur bei der Entwicklung installierter Desktopanwendungen verwenden. Für Webanwendungen wird die Verwendung von AuthSub oder OAuth empfohlen.
Die Ruby-Bibliothek enthält für jede API eine Clientklasse. Mit dem folgenden Code-Snippet können Sie sich beispielsweise mit user@gmail.com
in der Documents List Data API anmelden:
client = GData::Client::DocList.new client.clientlogin('user@gmail.com', 'pa$$word')
The YouTube Data API would be:
client = GData::Client::YouTube.new client.clientlogin('user@gmail.com', 'pa$$word')
Vollständige Liste der implementierten Dienstklassen
Wenn ein Dienst keine Clientklasse hat, verwenden Sie die Klasse GData::Client::Base
.
Im folgenden Beispielcode werden Nutzer gezwungen, sich mit einem G Suite-Konto anzumelden.
client_login_handler = GData::Auth::ClientLogin
.new('writely', :account_type => 'HOSTED')
token = client_login_handler.get_token('user@example.com', 'pa$$word', 'google-RailsArticleSample-v1')
client = GData::Client::Base.new(:auth_handler => client_login_handler)
Hinweis: Standardmäßig verwendet die Bibliothek HOSTED_OR_GOOGLE
für die accountType
. Mögliche Werte sind HOSTED_OR_GOOGLE
, HOSTED
und GOOGLE
.
Einer der Nachteile der Verwendung von ClientLogin besteht darin, dass Ihre Anwendung bei fehlgeschlagenen Anmeldeversuchen CAPTCHA-Herausforderungen erhalten kann. In diesem Fall können Sie den Fehler beheben, indem Sie die Methode clientlogin()
mit den zusätzlichen Parametern client.clientlogin(username, password, captcha_token, captcha_answer)
aufrufen. Weitere Informationen zum Umgang mit CAPTCHAs finden Sie in der vollständigen Dokumentation zur Authentifizierung für installierte Anwendungen.
AuthSub
AuthSubRequest-URL generieren
scope = 'http://www.google.com/calendar/feeds/' next_url = 'http://example.com/change/to/your/app' secure = false # set secure = true for signed AuthSub requests sess = true authsub_link = GData::Auth::AuthSub.get_url(next_url, scope, secure, sess)
Mit dem vorherigen Codeblock wird die folgende URL in authsub_link
erstellt:
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F&session=1&secure=0
Sie können auch die Methode authsub_url
des Clientobjekts verwenden. Für jede Dienstklasse wurde ein Standardattribut authsub_scope
festgelegt, sodass Sie kein eigenes angeben müssen.
client = GData::Client::DocList.new next_url = 'http://example.com/change/to/your/app' secure = false # set secure = true for signed AuthSub requests sess = true domain = 'example.com' # force users to login to a G Suite hosted domain authsub_link = client.authsub_url(next_url, secure, sess, domain)
Mit dem vorherigen Codeblock wird die folgende URL erstellt:
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=example.com
Einmal-Token in ein Sitzungstoken umwandeln
AuthSub leitet den Nutzer zurück zu http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN
, sobald er den Zugriff auf seine Daten gewährt hat. Die URL ist einfach unsere next_url
mit dem Einmal-Token als Suchparameter.
Tauschen Sie als Nächstes das Einmal-Token gegen ein langlebiges Sitzungstoken ein:
client.authsub_token = params[:token] # extract the single-use token from the URL query params session[:token] = client.auth_handler.upgrade() client.authsub_token = session[:token] if session[:token]
Secure AuthSub ist sehr ähnlich. Die einzige Ergänzung besteht darin, den privaten Schlüssel festzulegen, bevor Sie das Token aktualisieren:
PRIVATE_KEY = '/path/to/private_key.pem' client.authsub_token = params[:token] client.authsub_private_key = PRIVATE_KEY session[:token] = client.auth_handler.upgrade() client.authsub_token = session[:token] if session[:token]
Hinweis: Wenn Sie sichere Tokens verwenden möchten, müssen Sie secure=true
festlegen, wenn Sie ein Einmal-Token anfordern. Siehe oben AuthSubRequest-URL generieren.
Tokenverwaltung
AuthSub bietet zwei zusätzliche Handler, AuthSubTokenInfo und AuthSubRevokeToken, zum Verwalten von Tokens. AuthSubTokenInfo
ist nützlich, um die Gültigkeit eines Tokens zu prüfen. Mit AuthSubRevokeToken
haben Nutzer die Möglichkeit, den Zugriff auf ihre Daten zu beenden. Ihre App sollte AuthSubRevokeToken
als Best Practice verwenden. Beide Methoden werden in der Ruby-Bibliothek unterstützt.
So fragen Sie die Metadaten eines Tokens ab:
client.auth_handler.info
So widerrufen Sie ein Sitzungstoken:
client.auth_handler.revoke
Die vollständige Dokumentation zu AuthSub finden Sie unter AuthSub-Authentifizierung für Webanwendungen.
OAuth
Zum Zeitpunkt der Erstellung dieses Artikels wurde OAuth dem Modul GData::Auth
noch nicht hinzugefügt.
Die Verwendung von OAuth in der Utility-Bibliothek sollte relativ einfach sein, wenn Sie das Rails-OAuth-Plug-in oder das Ruby-OAuth-Gem verwenden. In beiden Fällen müssen Sie ein GData::HTTP::Request
-Objekt erstellen und den von jeder Bibliothek generierten Authorization
-Header übergeben.
Auf Feeds zugreifen
GET (Daten abrufen)
Nachdem Sie ein Clientobjekt eingerichtet haben, können Sie mit der Methode get()
einen Google Data-Feed abfragen. Mit XPath können Sie bestimmte Atom-Elemente abrufen. Hier ist ein Beispiel für das Abrufen der Google-Dokumente eines Nutzers:
feed = client.get('http://docs.google.com/feeds/documents/private/full').to_xml feed.elements.each('entry') do |entry| puts 'title: ' + entry.elements['title'].text puts 'type: ' + entry.elements['category'].attribute('label').value puts 'updated: ' + entry.elements['updated'].text puts 'id: ' + entry.elements['id'].text # Extract the href value from each <atom:link> links = {} entry.elements.each('link') do |link| links[link.attribute('rel').value] = link.attribute('href').value end puts links.to_s end
POST (neue Daten erstellen)
Verwenden Sie die post()
-Methode eines Clients, um neue Daten auf dem Server zu erstellen. Im folgenden Beispiel wird new_writer@example.com
als Mitbearbeiter für das Dokument mit der ID doc_id
hinzugefügt.
# Return documents the authenticated user owns feed = client.get('http://docs.google.com/feeds/documents/private/full/-/mine').to_xml entry = feed.elements['entry'] # first <atom:entry> acl_entry = <<-EOF <entry xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl='http://schemas.google.com/acl/2007'> <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/acl/2007#accessRule'/> <gAcl:role value='writer'/> <gAcl:scope type='user' value='new_writer@example.com'/> </entry> EOF # Regex the document id out from the full <atom:id>. # http://docs.google.com/feeds/documents/private/full/document%3Adfrk14g25fdsdwf -> document%3Adfrk14g25fdsdwf doc_id = entry.elements['id'].text[/full\/(.*%3[aA].*)$/, 1] response = client.post("http://docs.google.com/feeds/acl/private/full/#{doc_id}", acl_entry)
PUT (Daten aktualisieren)
Verwenden Sie die Methode put()
eines Clients, um Daten auf dem Server zu aktualisieren. Im folgenden Beispiel wird der Titel eines Dokuments aktualisiert.
Dabei wird davon ausgegangen, dass Sie einen Feed aus einer vorherigen Anfrage haben.
entry = feed.elements['entry'] # first <atom:entry> # Update the document's title entry.elements['title'].text = 'Updated title' entry.add_namespace('http://www.w3.org/2005/Atom') entry.add_namespace('gd','http://schemas.google.com/g/2005') edit_uri = entry.elements["link[@rel='edit']"].attributes['href'] response = client.put(edit_uri, entry.to_s)
LÖSCHEN
Wenn Sie ein <atom:entry> oder andere Daten vom Server löschen möchten, verwenden Sie die Methode delete()
.
Im folgenden Beispiel wird ein Dokument gelöscht. Im Code wird davon ausgegangen, dass Sie einen Dokumenteintrag aus einer vorherigen Anfrage haben.
entry = feed.elements['entry'] # first <atom:entry> edit_uri = entry.elements["link[@rel='edit']"].attributes['href'] client.headers['If-Match'] = entry.attribute('etag').value # make sure we don't nuke another client's updates client.delete(edit_uri)
Neue Rails-Anwendung erstellen
Normalerweise besteht die erste Übung beim Erstellen einer neuen Rails-Anwendung darin, die Scaffold-Generatoren auszuführen, um Ihre MVC-Dateien zu erstellen.
Danach wird rake db:migrate
ausgeführt, um Ihre Datenbanktabellen einzurichten. Da unsere Anwendung jedoch Daten über die Google Documents List API abfragen wird, benötigen wir kaum generische Gerüste oder Datenbanken. Erstellen Sie stattdessen eine neue Anwendung und einen einfachen Controller:
rails doclist cd doclist ruby script/generate controller doclist
Nehmen Sie die folgenden Änderungen an config/environment.rb
vor:
config.frameworks -= [ :active_record, :active_resource, :action_mailer ] config.gem 'gdata', :lib => 'gdata'
In der ersten Zeile wird ActiveRecord
aus der Anwendung entfernt.
In der zweiten Zeile wird das gdata
-Gem beim Start geladen.
Schließlich habe ich die Standardroute (/
) mit der Aktion documents
in DoclistController
verbunden.
Fügen Sie diese Zeile zu config/routes.rb
hinzu:
map.root :controller => 'doclist', :action => 'all'
Controller starten
Da wir kein Gerüst generiert haben, fügen Sie der DoclistController
in app/controllers/doclist_controller.rb
manuell eine Aktion mit dem Namen „all
“ hinzu.
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
und erstellen Sie all.html.erb
unter app/views/doclist/
:
<%= @foo %>
Webserver starten und mit der Entwicklung beginnen
Sie sollten jetzt den Standardwebserver starten können, indem Sie ruby script/server
aufrufen.
Wenn alles in Ordnung ist, sollte beim Aufrufen von http://localhost:3000/
in Ihrem Browser „I pity the foo!
“ angezeigt werden.
Tipp: Vergessen Sie nicht, public/index.html
zu entfernen oder umzubenennen.
Wenn alles funktioniert, sehen Sie sich die endgültigen DoclistController
und ApplicationController
an, um die wichtigsten Teile des DocList Manager-Projekts zu sehen. Sehen Sie sich auch ContactsController
an, das die Aufrufe der Google Contacts API verarbeitet.
Fazit
Der schwierigste Teil beim Erstellen einer Google Data Rails-App ist die Konfiguration von Rails. Gleich danach folgt die Bereitstellung Ihrer Anwendung. Dazu empfehle ich mod_rails für Apache. Die Einrichtung, Installation und Ausführung sind ganz einfach. Sie können sofort loslegen.
Ressourcen
- Liste der Google Data APIs
- Projektseite Google Data Ruby Utility Library
- Artikel: Using Ruby with the Google Data APIs (Google Data APIs mit Ruby verwenden)
- Ruby herunterladen
- RubyGems und Rails herunterladen
Anhang
Beispiele
Der DocList Manager ist ein vollständiges Ruby on Rails-Beispiel, das die in diesem Artikel behandelten Themen veranschaulicht. Der vollständige Quellcode ist über das Projekthosting verfügbar.