1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
|
<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 24249 -->
<!-- Reviewed: no -->
<sect2 id="zend.oauth.introduction.getting-started">
<title>Beginnen</title>
<para>
Da das OAuth Protokoll jetzt erklärt wurde sehen wir uns ein einfaches Beispiel mit
Quellcode an. Unser neuer Konsument wird Twitter Statusübertragungen verwenden. Um das tun
zu können muss er bei Twitter registriert sein um einen OAuth Konsumentenschlüssel und ein
Konsumentengeheimnis zu empfangen. Diese werden verwendet um einen Zugriffstoken zu
erhalten bevor wir die Twitter <acronym>API</acronym> verwenden um eine Statusmeldung zu
schicken.
</para>
<para>
Angenommen wir haben einen Schlüssel und ein Geheimnis bekommen, dann können wir den OAuth
Workflow starten indem eine <classname>Zend_Oauth_Consumer</classname> Instanz wie folgt
eingerichtet und eine Konfiguration übergeben wird (entweder ein Array oder ein
<classname>Zend_Config</classname> Objekt).
</para>
<programlisting language="php"><![CDATA[
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
);
$consumer = new Zend_Oauth_Consumer($config);
]]></programlisting>
<para>
callbackUrl ist die URI von der wir wollen das Sie Twitter von unserem Server anfragt wenn
Informationen gesendet werden. Wir sehen uns das später an. siteUrl ist die Basis URL der
OAuth <acronym>API</acronym> Endpunkte von Twitter. Die komplette Liste der Endpunkt enthält
http://twitter.com/oauth/request_token, http://twitter.com/oauth/access_token und
http://twitter.com/oauth/authorize. Die grundsätzliche siteUrl verwendet eine Konvention
welche auf diese drei OAuth Endpunkte verweist (als Standard) um einen Anfragetoken, den
Zugriffstoken oder die Authorisierung zu erhalten. Wenn sich der aktuelle Endpunkt eines
beliebigen Services vom Standardset unterscheidet, dann können diese drei URIs separat
gesetzt werden indem die Methoden <methodname>setRequestTokenUrl()</methodname>,
<methodname>setAccessTokenUrl()</methodname>, und
<methodname>setAuthorizeUrl()</methodname>, oder die Konfigurationsfelder requestTokenUrl,
accessTokenUrl und authorizeUrl verwendet werden.
</para>
<para>
consumerKey und consumerSecret werden von Twitter empfangen wenn sich die eigene Anwendung
für den OAuth Zugriff registriert. Das wird auch bei jedem OAuth aktivierten Service so
angewendet, so dass jeder einen Schlüssel und ein Geheimnis für die eigene Anwendung
anbietet.
</para>
<para>
Alle diese Konfigurationsoptionen müssen durch Verwendung von Methodenaufrufen gesetzt
werden indem Sie einfach von callbackUrl auf setCallbackUrl() konvertiert werden.
</para>
<para>
Zusätzlich sollte beachtet werden das verschiedene andere Konfigurationswerte nicht explizit
verwendet werden: requestMethod und requestScheme. Standardmäßig sendet
<classname>Zend_Oauth_Consumer</classname> Anfragen als POST (ausgenommen bei einer
Weiterleitung welche <constant>GET</constant> verwendet). Der konsumierende Client (siehe
später) enthält auch seine Authorisierung in Art eines Headers. Einige Services können, zu
Ihrer Diskretion, Alternativen benötigen. Man kann requestMethod (welche standardmäßig
Zend_Oauth::POST ist) zum Beispiel auf Zend_Oauth::GET zurückgesetzt, und requestScheme von
seinem Standardwert Zend_Oauth::REQUEST_SCHEME_HEADER entweder auf
Zend_Oauth::REQUEST_SCHEME_POSTBODY oder auf Zend_Oauth::REQUEST_SCHEME_QUERYSTRING.
Typischerweise sollten die Standardwerte bis auf ein paar bestimmte Ausnahmen problemlos
funktionieren. Für Details sehen Sie bitte in die Dokumentation des Service Providers.
</para>
<para>
Der zweite Teil der Anpassung definiert wie <acronym>HMAC</acronym> arbeitet wenn es für
alle Anfragen berechnet und verglichen wird. Das wird durch Verwendung des
Konfigurationsfeldes signatureMethod oder durch
<methodname>setSignatureMethod()</methodname> konfiguriert. Standardmäßig ist es HMAC-SHA1.
Man kann es auch auf die vom Provider bevorzugte Methode setzen inklusive RSA-SHA1. Für
RSA-SHA1 sollte man die privaten und öffentlichen RSA Schlüssel über die
Konfigurationsfelder rsaPrivateKey und rsaPublicKey oder die Methoden
<methodname>setRsaPrivateKey()</methodname> und <methodname>setRsaPublicKey()</methodname>
konfigurieren.
</para>
<para>
Der erste Teil des OAuth Workflows holt sich einen Anfragetoken. Das wird bewerkstelligt
indem folgendes verwendet wird:
</para>
<programlisting language="php"><![CDATA[
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
);
$consumer = new Zend_Oauth_Consumer($config);
// Holt den Anfragetoken
$token = $consumer->getRequestToken();
]]></programlisting>
<para>
Der neue Anfragetoken (eine Instanz von <classname>Zend_Oauth_Token_Request</classname>)
ist nicht authorisiert. Um Ihn mit einem authorisierten Token zu wechseln mit dem wir auf
die Twitter <acronym>API</acronym> zugreifen können, muss Ihn der Benutzer authorisieren.
Wir bewerkstelligen das indem der Benutzer auf den Authorisierungsendpunkt von Twitter
umgeleitet wird:
</para>
<programlisting language="php"><![CDATA[
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
);
$consumer = new Zend_Oauth_Consumer($config);
// Holt den Anfragetoken
$token = $consumer->getRequestToken();
// Den token im Speicher fixieren
$_SESSION['TWITTER_REQUEST_TOKEN'] = serialize($token);
// Den Benutzer umleiten
$consumer->redirect();
]]></programlisting>
<para>
Der Benutzer wird jetzt auf Twitter umgeleitet. Er wird gefragt den Anfragetoken zu
authorisieren, welcher an den Anfragestring der umgeleiteten URI angehängt ist. Angenommen
er akzeptiert und vervollständigt die Authorisierung, dann wird er wieder umgeleitet. Dieses
Mal auf unsere Callback URL die vorher gesetzt wurde (Beachte das die Callback URL auch in
Twitter registriert wurde als wir unsere Anwendung registriert haben).
</para>
<para>
Bevor der Benutzer umgeleitet wird, sollten wir den Anfragetoken im Speicher fixieren. Der
Einfachheit halber verwenden wir nur die Session des Benutzer, aber man kann sehr einfach
eine Datenbank für den gleichen Zweck verwenden, solange der Anfragetoken mit dem aktuellen
Benutzer verbunden bleibt, damit er empfangen werden kann wenn dieser zu unserer Anwendung
zurückkommt.
</para>
<para>
Die umgeleitete URI von Twitter enthält einen authorisierten Zugriffstoken. Wir können Code
einbauen um diesen Zugriffstoken wie folgt herauszuschneiden - dieser Sourcecode würde im
ausgeführten Code unserer Callback URI existieren. Sobald er herausgeschnitten wurde können
wir den vorherigen Anfragetoken entfernen, und statt dessen den Zugriffstoken für die
zukünftige Verendung mit der <acronym>API</acronym> von Twitter fixieren. Nochmals, wir
fixieren einfach die Session des Benutzer, aber in Wirklichkeit kann ein Zugriffstoken eine
lange Lebenszeit haben, und sollte deshalb wirklich in einer Datenbank abgespeichert werden.
</para>
<programlisting language="php"><![CDATA[
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
);
$consumer = new Zend_Oauth_Consumer($config);
if (!empty($_GET) && isset($_SESSION['TWITTER_REQUEST_TOKEN'])) {
$token = $consumer->getAccessToken(
$_GET,
unserialize($_SESSION['TWITTER_REQUEST_TOKEN'])
);
$_SESSION['TWITTER_ACCESS_TOKEN'] = serialize($token);
// Jetzt da wir den Zugriffstoken haben können wir den Anfragetoken löschen
$_SESSION['TWITTER_REQUEST_TOKEN'] = null;
} else {
// Fehlgeschlagene Anfrage? Ein Gauner versucht etwas?
exit('Ungültige Callback Anfrage. Oops. Entschuldigung.');
}
]]></programlisting>
<para>
Erfolg! Wir haben einen authorisierten Zugriffstoken - zu dieser Zeit verwenden wir schon
die <acronym>API</acronym> von Twitter. Da dieser Zugriffstoken bei jeder einzelnen
<acronym>API</acronym> Anfrage enthalten sein muss, bietet
<classname>Zend_Oauth_Consumer</classname> einen fix-fertigen <acronym>HTTP</acronym> Client
an (eine Subklasse von <classname>Zend_Http_Client</classname>) welcher entweder für sich
verwendet werden, oder der als eigener <acronym>HTTP</acronym> Client an eine andere
Bibliothek oder Komponente übergeben werden kann. Hier ist ein Beispiel für die
eigenständige Verwendung. Das kann von überall aus der Anwendung heraus getan werden,
solange man Zugriff auf die OAuth Konfiguration hat, und den endgültigen authorisierten
Zugriffstoken empfangen kann.
</para>
<programlisting language="php"><![CDATA[
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
);
$statusMessage = 'Ich sende über Twitter und verwende Zend_Oauth!';
$token = unserialize($_SESSION['TWITTER_ACCESS_TOKEN']);
$client = $token->getHttpClient($configuration);
$client->setUri('http://twitter.com/statuses/update.json');
$client->setMethod(Zend_Http_Client::POST);
$client->setParameterPost('status', $statusMessage);
$response = $client->request();
$data = Zend_Json::decode($response->getBody());
$result = $response->getBody();
if (isset($data->text)) {
$result = 'true';
}
echo $result;
]]></programlisting>
<para>
Als Notiz zum eigenen Client, kann dieser an den meisten Services von Zend Framework
übergeben werden, oder an andere Klassen welche <classname>Zend_Http_Client</classname>
verwenden um damit den Standardclient zu ersetzen welcher andernfalls verwendet werden
würde.
</para>
</sect2>
|