Luty 2009 r.
Wprowadzenie
„Gdzie jest Ruby na liście bibliotek klienta?”
Zachęcony gwałtownym apetytem naszych programistów i wieloletnią popularnością Ruby on Rails (RoR) mój kolega, Jeff Fisher, sfałszował bibliotekę Ruby z ogromnej głębokości góry Doom. Nie jest to kompleksowa biblioteka klienta, ale obsługuje takie podstawowe elementy, jak uwierzytelnianie czy podstawowa manipulacja XML. Wymaga też bezpośredniej pracy z kanałem Atom za pomocą modułu REXML i ścieżki XPath.
Odbiorcy
Ten artykuł jest przeznaczony dla deweloperów zainteresowanych korzystaniem z interfejsów API danych Google przy użyciu systemu Ruby, w szczególności Ruby on Rails. Zakładamy, że czytelnik ma wiedzę na temat języka programowania Ruby i platformy programowania stron internetowych The Rails. Postaram się skupić na interfejsie Documents List API dla większości przykładów, ale te same koncepcje można zastosować do dowolnych interfejsów Data API.
Pierwsze kroki
Wymagania
- Poprawka do pakietu Ruby 1.8.6 (poziom 114+) do pobrania
- RubyGems 1.3.1+ do pobrania
- Rails 2.2.2+ do pobrania
Instalowanie biblioteki narzędzi Google Data Ruby
Aby uzyskać bibliotekę, możesz pobrać źródło biblioteki bezpośrednio z projektu na serwerze lub zainstalować klejnot:
sudo gem install gdata
Wskazówka: aby mieć pewność, że klejnot został prawidłowo zainstalowany, uruchom gem list --local
.
Uwierzytelnianie
ClientLogin
ClientLogin pozwala aplikacji na automatyczne logowanie użytkowników na konta Google lub G Suite. Po zweryfikowaniu danych logowania użytkownika Google wysyła token uwierzytelniania, który może zostać użyty w kolejnych żądaniach do interfejsu API. Token pozostaje ważny przez określony czas zdefiniowany w dowolnej usłudze Google, z którą współpracujesz. Ze względów bezpieczeństwa i dla wygody użytkowników używaj tylko ClientLogin podczas tworzenia zainstalowanych aplikacji komputerowych. W przypadku aplikacji internetowych zalecamy korzystanie z AuthSub lub OAuth.
Biblioteka Ruby zawiera klasę klienta dla każdego z interfejsów API. Na przykład możesz użyć tego fragmentu kodu, aby zalogować się do user@gmail.com
za pomocą interfejsu Documents List Data API:
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')
Zobacz pełną listę wdrożonych klas usługi.
Jeśli usługa nie ma klasy klienta, użyj klasy GData::Client::Base
.
Na przykład ten kod wymusza na użytkownikach logowanie się za pomocą konta G Suite.
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)
Uwaga: domyślnie accountType
używa biblioteki HOSTED_OR_GOOGLE
. Możliwe wartości to HOSTED_OR_GOOGLE
, HOSTED
lub GOOGLE
.
Jedną z wad każdego z nich jest to, że w przypadku nieudanych prób logowania aplikacja może wysyłać testy CAPTCHA. W takim przypadku możesz usunąć błąd, wywołując metodę clientlogin()
z dodatkowymi parametrami: client.clientlogin(username, password, captcha_token, captcha_answer)
. Więcej informacji o korzystaniu z CAPTCHA znajdziesz w pełnej dokumentacji uwierzytelniania dla zainstalowanych aplikacji.
AuthSub
Generowanie adresu URL AuthSubRequest
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)
Poprzedni blok kodu tworzy w authsub_link
ten adres URL:
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
Możesz też użyć metody authsub_url
obiektu klienta. Każda klasa usługi ma ustawiony domyślny atrybut authsub_scope
, więc nie trzeba określać własnej.
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)
Poprzedni blok kodu tworzy ten adres URL:
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
Uaktualnienie tokena jednorazowego do tokena sesji
AuthSub przekieruje użytkownika z powrotem do http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN
po przyznaniu mu dostępu do danych. Zwróć uwagę, że adres URL to po prostu next_url
z tokenem jednorazowym dołączonym jako parametr zapytania.
Następnie wymień token jednorazowy na token długoterminowej sesji:
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]
Zabezpieczenie AuthSub jest bardzo podobne. Jedynym dodatkiem jest ustawienie klucza prywatnego przed uaktualnieniem tokena:
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]
Uwaga: jeśli chcesz używać tokenów bezpiecznych, ustaw żądanie jednorazowego tokena jako secure=true
. Przeczytaj sekcję Generowanie adresu URL AuthSubRequest powyżej.
Zarządzanie tokenami
AuthSub udostępnia 2 dodatkowe moduły obsługi: AuthSubTokenInfo i AuthSubRevokeToken do zarządzania tokenami. AuthSubTokenInfo
przydaje się do sprawdzania poprawności tokena. AuthSubRevokeToken
umożliwia użytkownikom odłączenie dostępu do ich danych. Sprawdzoną metodą jest używanie AuthSubRevokeToken
. Obie metody są obsługiwane w bibliotece Ruby.
Aby wysłać zapytanie do metadanych tokena:
client.auth_handler.info
Aby unieważnić token sesji:
client.auth_handler.revoke
Pełne informacje o AuthSub znajdziesz w pełnej dokumentacji uwierzytelniania AuthSub dla aplikacji internetowych.
OAuth
W momencie tworzenia tego artykułu do protokołu GData::Auth
nie dodano protokołu OAuth.
Korzystanie z protokołu OAuth w bibliotece narzędzi powinno być stosunkowo proste podczas korzystania z wtyczki oauth-plugin lub ruby oauth gem. W obu przypadkach musisz utworzyć obiekt GData::HTTP::Request
i przekazać do niego nagłówek Authorization
wygenerowany przez każdą bibliotekę.
Dostęp do kanałów
GET (pobieranie danych)
Po skonfigurowaniu obiektu klienta użyj jego metody get()
, aby utworzyć zapytanie dotyczące pliku danych Google. XPath może służyć do pobierania określonych elementów Atom. Oto przykład pobrania dokumentów Google użytkownika:
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 (tworzenie nowych danych)
Użyj metody post()
klienta, aby utworzyć nowe dane na serwerze. Ten przykład dodaje użytkownika new_writer@example.com
jako współpracownika do dokumentu o identyfikatorze: doc_id
.
# 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 (aktualizowanie danych)
Aby zaktualizować dane na serwerze, użyj metody put()
klienta. Poniższy przykład spowoduje zaktualizowanie tytułu dokumentu.
Przy założeniu, że masz plik danych z poprzedniego zapytania.
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)
USUŃ
Aby usunąć tag <atom:entry> lub inne dane z serwera, użyj metody delete()
.
Poniższy przykład spowoduje usunięcie dokumentu. Kod zakłada, że masz dokument z poprzedniego zapytania.
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)
Tworzenie nowej aplikacji Rails
Pierwszym ćwiczeniem w celu utworzenia nowej aplikacji Rails jest utworzenie generatorów rusztowań w celu utworzenia plików MVC.
Po tym czasie aplikacja korzysta z rake db:migrate
, aby konfigurować tabele bazy danych. Ponieważ jednak nasza aplikacja będzie wysyłać zapytania do interfejsu Google Documents List API, aby znaleźć dane, nie musimy już używać szkieletów lub baz danych. Zamiast tego utwórz nową aplikację i prosty kontroler:
rails doclist cd doclist ruby script/generate controller doclist
i wprowadź te zmiany w pliku config/environment.rb
:
config.frameworks -= [ :active_record, :active_resource, :action_mailer ] config.gem 'gdata', :lib => 'gdata'
Pierwszy wiersz odłącza wartość ActiveRecord
z aplikacji.
Drugi wiersz wczytuje klejnot gdata
przy uruchomieniu.
Na koniec zdecydowałem się połączyć trasę domyślną („/
”) z działaniem documents
w DoclistController
.
Dodaj ten wiersz do config/routes.rb
:
map.root :controller => 'doclist', :action => 'all'
Uruchom kontroler
Nie generowaliśmy rusztowania, więc ręcznie dodaj działanie o nazwie „all
” do DoclistController
w app/controllers/doclist_controller.rb
.
class DoclistController < ApplicationController def all @foo = 'I pity the foo!' end end
i utwórz all.html.erb
w app/views/doclist/
:
<%= @foo %>
Uruchom serwer WWW i zacznij programować
Teraz możesz uruchomić domyślny serwer WWW przez wywoływanie ruby script/server
.
Jeśli wszystko jest w porządku, ustaw w przeglądarce adres http://localhost:3000/
na „I pity the foo!
”.
Wskazówka: nie zapomnij usunąć nazwy public/index.html
lub zmienić jej nazwy.
Gdy wszystko będzie gotowe, zobacz moje ostateczne wersje: DoclistController
i ApplicationController
w projekcie dla menedżera projektu DocList. Możesz też użyć narzędzia ContactsController
, które obsługuje wywołania interfejsu Google Contacts API.
Podsumowanie
Najtrudniejszym etapem tworzenia aplikacji Google Data Rails jest konfigurowanie kolejek. Zbliża się jednak czas na wdrożenie aplikacji. Zalecamy korzystanie z serwera mod_rails na serwerze Apache. Konfiguracja, instalacja i uruchomienie są bardzo łatwe. Możesz zacząć działać od razu.
Zasoby
- Lista interfejsów API danych Google
- Strona projektu Biblioteki danych Google Ruby
- Artykuł: Używanie Ruby z interfejsami API danych Google
- Pobierz Ruby
- Pobierz RubyGems i rails
Dodatek
Przykłady
Menedżer DocList to pełna próbka Ruby on Rails, która obejmuje tematy omówione w tym artykule. Pełny kod źródłowy jest dostępny w usłudze hostingowej.