{"id":55000790,"date":"2011-08-01T00:00:00","date_gmt":"2020-05-22T21:57:16","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=790"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/","title":{"rendered":"Authentifizieren mit OAuth am Beispiel von Twitter"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Mit dem Automatisieren des Webdienstes Twitter hat Access im Unternehmen sich bereits besch&auml;ftigt. Allerdings hat Twitter mittlerweile die Authentifizierungsmethode gewechselt &#8211; auf das sogenannte OAuth. Die Programmierung des Zugriffs ist nicht ganz trivial, vor allem wegen der Erzeugung des notwendigen HMAC-SHA1-Ausdrucks, der zur Authentifizierung der Anfrage dient. Wie dies gel&ouml;st wurde und wie der Zugriff auf Twitter nun funktioniert, erfahren Sie in diesem Beitrag.<\/b><\/p>\n<p>Im Beitrag <b>Twittern mit Access <\/b>(<b>www.access-im-unternehmen.de\/715<\/b>) haben wir uns erstmalig mit Twitter besch&auml;ftigt. Damals gelang der Zugriff auf den Twitter-Webdienst noch &uuml;ber das einfache Basic Auth.<\/p>\n<p>Im Herbst 2010 hat Twitter dies jedoch auf OAuth umgestellt. Der Beitrag <b>Twittern mit Access, Update <\/b>(<b>www.access-im-unternehmen.de\/774<\/b>) lieferte eine erste M&ouml;glichkeit, mit OAuth zu arbeiten und somit wieder per VBA am Twitter-Geschehen teilnehmen zu k&ouml;nnen.<\/p>\n<p>Dies gelang &uuml;ber einen externen Anbieter, der die Authentifizierung auf Basis der &uuml;bermittelten Daten vorgenommen hat. Die Performance leidet hier nat&uuml;rlich, au&szlig;erdem wei&szlig; man nie, ob dieser (kostenlose) Anbieter nicht fr&uuml;her oder sp&auml;ter seine Pforten schlie&szlig;t.<\/p>\n<p>Also wirft der vorliegende Beitrag einen etwas genaueren Blick auf OAuth. Vollst&auml;ndig zu entschl&uuml;sseln brauchten wir dies nicht &#8211; im Internet fand sich der eine oder andere Codeschnipsel, der die L&ouml;sung erleichterte.<\/p>\n<p><b>Grundlagen<\/b><\/p>\n<p>Grundlegende Informationen zu Twitter finden Sie im Beitrag <b>Twittern mit Access <\/b>(<b>www.access-im-unternehmen.de\/715<\/b>) und nat&uuml;rlich auf <b>twitter.com <\/b>selbst.<\/p>\n<p><b>Voraussetzungen<\/b><\/p>\n<p>F&uuml;r den Zugriff auf die Twitter-Schnittstelle per OAuth-Authentifizierung ben&ouml;tigen Sie einige Informationen. Als Erstes m&uuml;ssen Sie einen Twitter-Account anlegen, was Sie unter <b>twitter.com <\/b>erledigen k&ouml;nnen (siehe Bild 1). Im n&auml;chsten Schritt best&auml;tigen Sie dann die Benutzungsrichtlinien und erstellen Ihr Konto. Sie k&ouml;nnen dann einige Benutzer ausw&auml;hlen, denen Sie folgen und deren Statusmeldungen Sie lesen m&ouml;chten. Sie erhalten eine Best&auml;tigungs-E-Mail von Twitter, die einen Link zum Abschlie&szlig;en des Registrierungsvorgangs enth&auml;lt.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic001.png\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Registrieren bei twitter.com<\/span><\/b><\/p>\n<p><b>Anwendung erstellen<\/b><\/p>\n<p>Wechseln Sie nach erfolgter Registrierung zu <b>dev.twitter.com<\/b>. Klicken Sie dort oben auf <b>Your Apps<\/b>. Es erscheint die &Uuml;bersicht der Anwendungen des aktuellen Kontos. Wenn Sie noch keine Anwendung erstellt haben, erledigen Sie dies jetzt mit einem Klick auf den Link <b>Register a new application<\/b> (s. Bild 2).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic002.png\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Erstellen einer neuen Anwendung<\/span><\/b><\/p>\n<p>Im folgenden Dialog tragen Sie nun die Eigenschaften der Anwendung ein (s. Bild 3):<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic003.png\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Eingeben der Anwendungsdaten<\/span><\/b><\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Application Name<\/b>: Name der Anwendung, darf nicht <b>Twitter <\/b>enthalten<\/li>\n<li class=\"aufz-hlung\"><b>Description<\/b>: Beschreibung<\/li>\n<li class=\"aufz-hlung\"><b>Application Website<\/b>: Webadresse, unter der Benutzer die Anwendung herunterladen k&ouml;nnen, darf nicht leer sein<\/li>\n<li class=\"aufz-hlung\"><b>Application Type<\/b>: Anwendungstyp, hier <b>Client <\/b>ausw&auml;hlen<\/li>\n<li class=\"aufz-hlung\"><b>Default Access Type<\/b>: Zugriffsart, hier <b>Read, Write And Direct Messages <\/b>ausw&auml;hlen<\/li>\n<\/ul>\n<p>Nach der Eingabe des Captcha-Codes registriert Twitter Ihre Anwendung. Auf der folgenden Seite erhalten Sie dann wichtige Informationen, die Sie sp&auml;ter etwa zum Authentifizieren vor dem Zugriff auf <b>twitter.com <\/b>via VBA ben&ouml;tigen (s. Bild 4).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic005.png\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Informationen zur Authentifizierung<\/span><\/b><\/p>\n<p>Wo Sie gerade einmal hier sind: In der Beispieldatenbank zu diesem Beitrag finden Sie eine Tabelle namens <b>tblApplications<\/b> (s. Bild 4 liefert beispielsweise die Werte f&uuml;r die Felder <b>ConsumerKey <\/b>und <b>ConsumerSecret<\/b>. F&uuml;r <b>ApplicationName <\/b>k&ouml;nnen Sie den Namen der Anwendung eintragen (dieses Feld dient lediglich der Identifizierung der zugeordneten Anwendung und hat keine Bedeutung f&uuml;r die Anwendung). <b>SignatureMethod <\/b>erh&auml;lt den Wert <b>HMAC-SHA1<\/b>, f&uuml;r die <b>Version <\/b>legen Sie den Wert <b>1.0 <\/b>fest.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic004.png\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: Tabelle zum Speichern der Zugriffsdaten<\/span><\/b><\/p>\n<p>Die beiden &uuml;brigen Werte <b>Token <\/b>und <b>TokenSecret <\/b>erhalten Sie, wenn Sie rechts auf den Link <b>My Access Token <\/b>klicken. Tragen Sie die beiden Werte aus der nun erscheinenden &Uuml;bersicht (s. Bild 6) in die Tabelle <b>tblApplications <\/b>ein.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic006.png\" alt=\"pic006.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Ermitteln von Access Token und Secret<\/span><\/b><\/p>\n<p>Damit sind die Arbeiten auf <b>twitter.com <\/b>abgeschlossen &#8211; sp&auml;ter werden Sie hier allerdings nachschauen, ob die von Access aus gesendeten Statusmeldungen auch dort angekommen sind.<\/p>\n<p><b>Basisausstattung<\/b><\/p>\n<p>Um das Rad nicht neu zu erfinden, bauen wir die L&ouml;sung dieses Beitrags auf der aus <b>Twittern mit Access <\/b>(<b>www.access-im-unternehmen.de\/715<\/b>) auf. Dort hatten wir bereits ein Formular programmiert, das vorhandene Statusmeldungen anzeigte und das Absenden neuer Statusmeldungen erm&ouml;glichte. Au&szlig;erdem konnten Sie dort vorhandene Statusmeldungen l&ouml;schen (s. Bild 7).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2011_04\/TwitterOAuth-web-images\/pic007.png\" alt=\"pic007.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 7: Die Benutzeroberfl&auml;che des Beispielformulars<\/span><\/b><\/p>\n<p>Ein wichtiger Unterschied zur damaligen L&ouml;sung besteht darin, dass das Kombinationsfeld nicht mehr zur Auswahl eines Benutzers dient, sondern zur Ermittlung der zu verwendenden Anwendungsdaten. Wenn Sie mehrere Applications unter Ihrem Account anlegen m&ouml;chten, k&ouml;nnen Sie die damit zusammenh&auml;ngenden Daten in verschiedenen Datens&auml;tzen der Tabelle <b>tblApplications <\/b>speichern.<\/p>\n<p>Grunds&auml;tzlich ist die Beispiell&ouml;sung als Single-User-L&ouml;sung zu betrachten. Sie k&ouml;nnen damit zwar verschiedene Daten von Twitter lesen (wie Benutzerdaten, Tweets, Follower et cetera), aber nur Statusmeldungen f&uuml;r den Benutzer erstellen oder l&ouml;schen, in dessen Kontext Sie die Application bei Twitter erstellt haben.<\/p>\n<p>Grunds&auml;tzlich ist es m&ouml;glich, mit einer Anwendung auch die Daten anderer Benutzer zu &auml;ndern &#8211; das w&auml;re interessant, wenn Sie die Beispiell&ouml;sung nicht nur f&uuml;r sich selbst verwenden wollen, sondern diese an andere Benutzer weitergeben m&ouml;chten.<\/p>\n<p>Diese melden sich dann mit ihren eigenen Daten an und k&ouml;nnen selbst Statusmeldungen erstellen und l&ouml;schen, Direktnachrichten versenden und so weiter. Der dazu n&ouml;tige Workflow ist allerdings noch ein wenig aufwendiger als der nachfolgend vorgestellte. Gegebenenfalls gehen wir in einem weiteren Beitrag auf diese Erweiterung ein.<\/p>\n<p><b>Formular der Beispiell&ouml;sung<\/b><\/p>\n<p>Das Formular stellt also zun&auml;chst ein Kombinationsfeld zur Auswahl der zu verwendenden Anwendungsdaten zur Verf&uuml;gung, das mit den ersten beiden Feldern der Tabelle <b>tblApplications <\/b>als Datensatzherkunft gef&uuml;llt ist.<\/p>\n<p>Beim &Ouml;ffnen des Formulars stellt die folgende, durch das Ereignis <b>Beim Laden <\/b>ausgel&ouml;ste Prozedur zun&auml;chst das Kombinationsfeld auf den ersten Eintrag ein.<\/p>\n<p>Au&szlig;erdem ruft sie die Prozedur <b>TweetsLaden <\/b>auf, die f&uuml;r das F&uuml;llen des Listenfeldes mit Ihren letzten Statusmeldungen verantwortlich ist:<\/p>\n<pre>Private Sub Form_Load()\r\n    Me!cboApplication = _\r\n    Me!cboApplication.ItemData(0)\r\n    Call TweetsLaden\r\n    End Sub<\/pre>\n<p>Die Prozedur <b>TweetsLaden <\/b>ruft wiederum eine Funktion namens <b>GetTweets_Listbox <\/b>auf, die eine Zeichenkette mit den im Listenfeld anzuzeigenden Daten zur&uuml;ckliefert. Das Ergebnis landet umgehend in der Eigenschaft <b>RowSource <\/b>des Listenfelds und sieht beispielsweise so aus:<\/p>\n<pre>&quot;85580978990493696&quot;;&quot;28.06.2011 05:31:10&quot;;&quot;Beispielstatusmeldung&quot;;&quot;83562060692209664&quot;;&quot;22.06.2011 15:48:42&quot;;&quot;Noch eine Beispielstatusmeldung&quot;;...<\/pre>\n<p>Danach markiert die Prozedur den ersten Eintrag des Listenfeldes und ruft die Routine <b>TweetAnzeigen <\/b>auf:<\/p>\n<pre>Private Sub TweetsLaden()\r\n    Me!lstTweets.RowSource = GetTweets_Listbox(Me!cboApplication)\r\n    Me!lstTweets = Me!lstTweets.ItemData(0)\r\n    Call TweetAnzeigen\r\n    End Sub<\/pre>\n<p><b>TweetAnzeigen <\/b>hat nichts weiter zu tun, als das Datum der aktuell markierten Statusmeldung und ihren Text aus der Datensatzherkunft des Listenfeldes auszulesen und in die beiden Textfelder <b>txtDatum <\/b>und <b>txtTweet <\/b>einzutragen:<\/p>\n<pre>Private Sub TweetAnzeigen()\r\n    Me!txtDatum = Me!lstTweets.Column(1)\r\n    Me!txtTweet = Me!lstTweets.Column(2)\r\n    End Sub<\/pre>\n<p>Ein Klick auf einen der &uuml;brigen Eintr&auml;ge im Listenfeld l&ouml;st die folgende Ereignisprozedur aus, die ebenfalls die Prozedur zum Anzeigen der Details der Statusmeldung aufruft:<\/p>\n<pre>Private Sub lstTweets_AfterUpdate()\r\n    TweetAnzeigen\r\n    End Sub<\/pre>\n<p>Das Aktualisieren des Listenfeldes erreicht der Benutzer durch einen Klick auf die Schaltfl&auml;che <b>cmdTweetsLaden<\/b>:<\/p>\n<pre>Private Sub cmdTweetsLaden_Click()\r\n    Call TweetsLaden\r\n    End Sub<\/pre>\n<p>Neue Statusmeldungen schreibt der Benutzer in das Textfeld <b>txtNeuerTweet<\/b>. Damit der Benutzer immer wei&szlig;, wie viele Zeichen noch verbleiben, l&ouml;st das Eingeben eines Zeichens jeweils das Ereignis <b>Bei &auml;nderung <\/b>aus. Die entsprechende Ereignisprozedur sieht wie folgt aus:<\/p>\n<pre>Private Sub txtNeuerTweet_Change()\r\n    Dim intZeichenUebrig As Integer\r\n    Dim intPos As Integer\r\n    intZeichenUebrig = _\r\n    140 - Len(Me!txtNeuerTweet.Text)\r\n    If intZeichenUebrig &lt; 0 Then\r\n        intPos = Me!txtNeuerTweet.SelStart\r\n        Me!txtNeuerTweet = strTweet\r\n        Me!txtNeuerTweet.SelStart = intPos - 1\r\n    Else\r\n        Me!txtZeichenUebrig = intZeichenUebrig\r\n        strTweet = Me!txtNeuerTweet.Text\r\n    End If\r\n    End Sub<\/pre>\n<p>Sie ermittelt aus der aktuellen Textl&auml;nge die verbleibenden Zeichen. Ist die Anzahl der Zeichen gr&ouml;&szlig;er oder gleich 0, wird der aktuelle Text in der Variablen <b>strTweet<\/b> gespeichert. Sollte diese Anzahl kleiner als 0 werden, stellt die Prozedur den Text vor der Eingabe dieses Zeichens aus der Variablen <b>strTweet <\/b>wieder her. Zum Absenden der Statusmeldung klickt der Benutzer auf die Schaltfl&auml;che <b>cmdTweetSenden<\/b>. Diese ruft die Funktion <b>NeuerStatus <\/b>auf, die nach dem erfolgreichen Versenden die ID der neuen Statusmeldung zur&uuml;ckliefert. Ist dies der Fall, sorgt ein erneuter Aufruf der Prozedur <b>TweetsLaden<\/b> daf&uuml;r, dass das Listenfeld der zuletzt erstellten Statusmeldungen aktualisiert wird:<\/p>\n<pre>Private Sub cmdTweetSenden_Click()\r\n    Dim strID As String\r\n    strID = NeuerStatus(Me!cboApplication, _\r\n    Me!txtNeuerTweet)\r\n    If Len(strID) &gt; 0 Then\r\n        Call TweetsLaden\r\n    End If\r\n    End Sub<\/pre>\n<p>Fehlt nur noch das L&ouml;schen der aktuell markierten Statusmeldung. Dies wird durch einen Klick auf die Schaltfl&auml;che <b>cmdTweetLoeschen <\/b>erreicht.<\/p>\n<p>Die folgende Prozedur ruft dann die Funktion <b>StatusLoeschen <\/b>auf, die nach erfolgter L&ouml;schung den Wert <b>True <\/b>zur&uuml;ckliefert. Dies wird durch das Aktualisieren des Listenfeldes quittiert:<\/p>\n<pre>Private Sub cmdTweetLoeschen_Click()\r\n    If StatusLoeschen(Me!cboApplication, _\r\n    Me!lstTweets) = True Then\r\n    Call TweetsLaden\r\nEnd If\r\nEnd Sub<\/pre>\n<p>Dies zur Funktionsweise des Formulars &#8211; in den folgenden Abschnitten schauen wir uns an, was unter der Haube passiert, sprich: Wie der Zugriff auf die Twitter-API vonstatten geht.<\/p>\n<p><b>Grundlegender Zugriff auf Twitter<\/b><\/p>\n<p>Um es vorwegzunehmen: Der Zugriff auf die Twitter-API mit der Authentifizierung per <b>OAuth<\/b> ist sehr aufwendig im Vergleich mit der zuvor m&ouml;glichen Anmeldung per <b>Basic Auth<\/b>.<\/p>\n<p>F&uuml;r den Zugriff ben&ouml;tigen Sie zun&auml;chst einmal eine Reihe Parameter, die zum gr&ouml;&szlig;ten Teil aus der Tabelle <b>tblApplications <\/b>bezogen werden k&ouml;nnen. Zus&auml;tzlich ben&ouml;tigen Sie den Link f&uuml;r den Zugriff auf die gew&uuml;nschte API-Funktion und die Zugriffsart (<b>POST<\/b>\/<b>GET<\/b>).<\/p>\n<p>Den Link f&uuml;r den Zugriff entnehmen Sie der Dokumentation, f&uuml;r das Versenden einer neuen Statusmeldung etwa unter <b>http:\/\/dev.twitter.com\/doc\/post\/statuses\/update<\/b>. Auf dieser Seite finden Sie am rechten Rand Links zu allen m&ouml;glichen Aktionen, die Sie mit der Twitter-API ausf&uuml;hren k&ouml;nnen.<\/p>\n<p>F&uuml;r das Aktualisieren des Status rufen Sie beispielsweise die folgende Adresse auf:<\/p>\n<pre>http:\/\/api.twitter.com\/[version]\/statuses\/update.[format]<\/pre>\n<p>Die Platzhalter <b>[version] <\/b>und <b>[format] <\/b>ersetzen wir in der Beispiell&ouml;sung durch <b>1 <\/b>und <b>xml<\/b>. In der Dokumentation erfahren Sie auch, dass das Aktualisieren des Status eine <b>POST<\/b>-Anfrage n&ouml;tig macht und dass eine Authentifizierung n&ouml;tig ist.<\/p>\n<p><!--30percent--><\/p>\n<p>Die API-Funktion erwartet au&szlig;erdem einen Parameter namens <b>status<\/b>, der den Text der neuen Statusmeldung enth&auml;lt. Der nackte Aufruf zum &auml;ndern des aktuellen Status sieht also etwa so aus:<\/p>\n<pre>http:\/\/api.twitter.com\/1\/statuses\/update.xmlstatus=Dies%20ist%20ein%20neuer%20Status<\/pre>\n<p>Leer- und Sonderzeichen in der als Parameter &uuml;bergebenen Statusmeldung werden durch URL-encodierte Zeichen ersetzt, beim Leerzeichen etwa durch <b>%20<\/b>. Dies entspricht dem ASCII-Code des Leerzeichens (<b>32<\/b>) in hexadezimaler Schreibweise (<b>20<\/b>) plus einem vorangestellten Prozentzeichen, damit die API-Funktion die encodierten Zeichen erkennen und entsprechend zur&uuml;ckverwandeln kann.<\/p>\n<p>Nun w&auml;re es leicht, diesen API-Aufruf abzusetzen.Dies ginge beispielsweise so:<\/p>\n<pre>Set objXMLHTTP = CreateObject(&quot;MSXML2.XMLHTTP&quot;)\r\nWith objXMLHTTP\r\n.Open &quot;POST&quot;, &quot; http:\/\/api.twitter.com\/1\/\r\nstatuses\/update.xmlstatus=\r\nDies%20ist%20ein%20neuer%20Status&quot;, False\r\n.Send\r\nDebug.Print .responseText\r\nEnd With<\/pre>\n<p>Das Problem ist nur, dass die Twitter-API Sie ohne vorherige Authentifizierung per OAuth mit einem lapidaren <b>Could not authenticate you <\/b>wieder nach Hause schickt.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Authentifizieren mit OAuth<\/p>\n<p>Also begeben wir uns auf den Weg, eine Authentifizierung per OAuth zu programmieren.<\/p>\n<p>Dazu brauchen Sie zuerst einmal eine Liste der notwendigen Parameter:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>oauth_nonce<\/b>: Zuf&auml;llige, 40 Zeichen lange Zeichenfolge<\/li>\n<li class=\"aufz-hlung\"><b>oauth_signature_method<\/b>: HMAC-SHA1<\/li>\n<li class=\"aufz-hlung\"><b>oauth_timestamp<\/b>: Aktuelle Zeit im UNIX-Format<\/li>\n<li class=\"aufz-hlung\"><b>oauth_token<\/b>: Token aus der Tabelle <b>tblApplications<\/b><\/li>\n<li class=\"aufz-hlung\"><b>oauth_version<\/b>: 1.0<\/li>\n<li class=\"aufz-hlung\"><b>oauth_consumer_key<\/b>: <b>ConsumerKey <\/b>aus der Tabelle <b>tblApplications<\/b><\/li>\n<\/ul>\n<p>Diese Parameter m&uuml;ssen in alphabetischer Reihenfolge sortiert und aneinandergeh&auml;ngt werden &#8211; etwa so:<\/p>\n<pre>oauth_consumer_key=W1wBuWOeTuendKsZKaBgfg&amp;oauth_nonce=AIIWczdtLGKu4VJATkdpV6vQXcXDmL46OaP7a7es\r\n&amp;oauth_signature_method=HMAC-SHA1&amp;oauth_timestamp=1309283138&amp;oauth_token=78842002-\r\ncOj7O8MOOUI07WP4Oam8SSNc5yv7W9tmyEvstcRw&amp;oauth_version=1.0&amp;status=Dies%20ist%20ein%20neuer%20Status<\/pre>\n<p>In diesem Beispiel kommt noch der Parameter <b>status <\/b>hinzu. Da je nach API-Aufruf ein oder mehrere verschiedene Parameter zum Einsatz kommen, ger&auml;t das Aneinanderketten der Parameter zu einer dynamischen Angelegenheit.<\/p>\n<p>In der Beispiell&ouml;sung haben wir daher eine Tabelle namens <b>tblParameter <\/b>angelegt, die alle f&uuml;r den jeweiligen API-Aufruf notwendigen Parameter speichert. Sp&auml;ter werden die Parameter in einem Recordset auf Basis dieser Tabelle mit einer einfachen <b>ORDER BY<\/b>-Klausel sortiert und in der richtigen Reihenfolge zusammengesetzt.<\/p>\n<p>Dieser Parameterliste f&uuml;gt die Prozedur der Beispiell&ouml;sung noch die Zugriffsmethode (hier <b>POST<\/b>) und den Link zur API-Funktion hinzu (<b>http:\/\/api.twitter.com\/1\/statuses\/update.xml<\/b>). Der resultierende Ausdruck wird wieder URL-encodiert und sieht dann beispielsweise so aus:<\/p>\n<pre>POST&amp;http%3A%2F%2Fapi.twitter.com%2F1%2Fstatuses%2Fupdate.xml&amp;oauth_consumer_key%3DW1wBuWOeTuendKsZKaBgfg\r\n%26oauth_nonce%3DRHJrsWaVYRcz1Xx72d6wGVdKDsMOqrZZK94oR8pH%26oauth_signature_method%3DHMAC-SHA1\r\n%26oauth_timestamp%3D1309283809%26oauth_token%3D78842002-cOj7O8MOOUI07WP4Oam8SSNc5yv7W9tmyEvstcRw\r\n%26oauth_version%3D1.0%26status%3DDies%2520ist%2520ein%2520neuer%2520Status<\/pre>\n<p>Dieser Ausdruck ist der Basisausdruck zum Ermitteln einer Signatur. Daneben ben&ouml;tigen Sie noch einen Key. Diesen bezieht die Prozedur <b>DoTwitter<\/b> aus den Feldern <b>ConsumerSecret <\/b>und <b>TokenSecret <\/b>der Tabelle <b>tblApplications<\/b>. Beide werden durch ein Kaufmanns-Und getrennt zusammengesetzt.<\/p>\n<p>Mit diesen Informationen ermittelt die L&ouml;sung wiederum die f&uuml;r die Authentifizierung notwendige Signatur. Dieser Vorgang ist sehr kompliziert und wird zum gr&ouml;&szlig;ten Teil in einer eigenen Klasse durchgef&uuml;hrt. Die Signatur ist eine Zeichenkette wie die folgende:<\/p>\n<pre>vP69PAcskjJ59vqHJRb04huocYs%3D<\/pre>\n<p>Wozu diese Signatur Sie ist ein Extrakt aus den zu &uuml;bermittelnden Daten, also den Informationen, die in der Parameterliste aufgef&uuml;hrt werden, sowie von Daten, die nicht &uuml;bertragen werden &#8211; n&auml;mlich dem Key, der aus den beiden geheimen Schl&uuml;sseln aus der Tabelle <b>tblApplications <\/b>besteht.<\/p>\n<p>Die Signatur wird zur Authentifizierung gemeinsam mit den &ouml;ffentlichen Parametern an Twitter gesendet, das ja die geheimen Informationen aus der Tabelle <b>tblApplications <\/b>ebenfalls kennt. Twitter kann dann pr&uuml;fen, ob die Signatur zu den &uuml;bermittelten Daten und den beiden Schl&uuml;sseln passt.<\/p>\n<p>Dadurch wird verhindert, dass auf dem Wege zwischen der Anwendung und Twitter die zu &uuml;bermittelnden Daten von Dritten ge&auml;ndert werden. Sollte dies geschehen, w&uuml;rde die Signatur nicht mehr zu den &uuml;bermittelten Daten passen und Twitter w&uuml;rde die Anmeldung zur&uuml;ckweisen.<\/p>\n<p>Die komplizierte Ermittlung der Signatur ist dabei darauf zur&uuml;ckzuf&uuml;hren, dass Dritte keine M&ouml;glichkeit haben sollen, aus den gesendeten &ouml;ffentlichen Parametern und der Signatur die geheimen Schl&uuml;ssel zu ermitteln, und somit die Anfrage &auml;ndern oder eigene Anfragen senden k&ouml;nnen.<\/p>\n<p><b>OAuth per VBA<\/b><\/p>\n<p>In der Beispiell&ouml;sung werden die Authentifizierung und gleichzeitig die &Uuml;bermittlung der Anfrage inklusive Annahme der Antwort durch die Prozedur <b>DoTwitter <\/b>erledigt (s. Listing 1). Die Prozedur erwartet die folgenden Parameter:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>lngApplicationID<\/b>: ID des Datensatzes aus <b>tblApplications<\/b>, dessen Daten zur Authentifizierung verwendet werden sollen<\/li>\n<li class=\"aufz-hlung\"><b>strAction<\/b>: Aufruf der Twitter-API, zum Beispiel <b>http:\/\/api.twitter.com\/1\/statuses\/update.xml <\/b><\/li>\n<li class=\"aufz-hlung\"><b>strMethod<\/b>: Methode des Aufrufs (<b>POST<\/b>\/<b>GET<\/b>)<\/li>\n<li class=\"aufz-hlung\"><b>ParamArray strParameters()<\/b>: Parameternamen und -werte des Aufrufs, bei <b>update.xml <\/b>beispielsweise <b>status <\/b>und <b>[Statusmeldung]<\/b>. Durch die Verwendung des <b>ParamArray<\/b>-Schl&uuml;sselwortes k&ouml;nnen beliebig viele Parameter &uuml;bergeben werden.<\/li>\n<\/ul>\n<p class=\"listingueberschrift\">Listing 1: Das Grundger&uuml;st f&uuml;r den Zugriff auf die Twitter-API<\/p>\n<pre>01 Public Function DoTwitter(lngApplicationID As Long, strAction As String, strMethod As String, _\r\n02     ParamArray strParameters() As Variant) As MSXML2.DOMDocument\r\n03     Dim strSignatureBase As String\r\n04     Dim strSignatureKey As String\r\n05     Dim strSignature As String\r\n06     Dim db As DAO.Database\r\n07     Dim strParameterliste As String\r\n08     Dim strOAuthHeader As String\r\n09     Dim objXMLHTTP As MSXML2.XMLHTTP\r\n10     Dim objXML As MSXML2.DOMDocument\r\n11     Dim i As Integer\r\n12     Set db = CurrentDb\r\n13     db.Execute &quot;DELETE FROM tblParameters&quot;, dbFailOnError\r\n14     SetSignatureBaseParameters lngApplicationID\r\n15     For i = LBound(strParameters) To UBound(strParameters) Step 2\r\n17         AddParameter strParameters(i), URLEncode(CStr(strParameters(i + 1)))\r\n18         strParameterliste = strParameterliste &amp; &quot;&amp;&quot; &amp; strParameters(i) &amp; &quot;=&quot; _\r\n19             &amp; URLEncode(CStr(strParameters(i + 1)))\r\n20     Next i\r\n21     If Left(strParameterliste, 1) = &quot;&amp;&quot; Then\r\n22         strParameterliste = Mid(strParameterliste, 2)\r\n23     End If\r\n24     strSignatureBase = strMethod &amp; &quot;&amp;&quot; &amp; URLEncode(strAction) &amp; &quot;&amp;&quot; &amp; URLEncode(GetParameters)\r\n25     strSignatureKey = DLookup(&quot;ConsumerSecret&quot;, &quot;tblApplications&quot;, &quot;ID = &quot; &amp; lngApplicationID) _\r\n26         &amp; &quot;&amp;&quot; &amp; DLookup(&quot;TokenSecret&quot;, &quot;tblApplications&quot;, &quot;ID = &quot; &amp; lngApplicationID)\r\n27     strSignature = GetSignature(strSignatureBase, strSignatureKey)\r\n28     strOAuthHeader = GetOAuthHeader(strSignature, strAction)\r\n29     Set objXMLHTTP = CreateObject(&quot;MSXML2.XMLHTTP&quot;)\r\n30     With objXMLHTTP\r\n31         .Open strMethod, strAction &amp; &quot;&quot; &amp; strParameterliste, False\r\n32         .setRequestHeader &quot;Authorization&quot;, strOAuthHeader\r\n33         .Send\r\n34         Set objXML = New MSXML2.DOMDocument\r\n35         objXML.loadXML CStr(.responseText)\r\n36         Set DoTwitter = objXML\r\n37     End With\r\n38     Set objXMLHTTP = Nothing\r\n39 End Function<\/pre>\n<p>Die Prozedur l&ouml;scht zun&auml;chst eventuell noch vorhandene Parameter aus der Tabelle <b>tblParameter<\/b> (Zeile 13). Dann erstellt sie ein neues Recordset auf Basis dieser Tabelle, das gleich an die Routine <b>SetSignatureBaseParameters <\/b>&uuml;bergeben wird (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-43-anchor\">Listing 2<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 2: Zusammenstellen der Basisparameter f&uuml;r die Authentifizierung<\/p>\n<pre>Public Sub SetSignatureBaseParameters(lngApplicationID As Long)\r\n    AddParameter &quot;oauth_nonce&quot;, GetOAuthNonce(40)\r\n    AddParameter &quot;oauth_signature_method&quot;, &quot;HMAC-SHA1&quot;\r\n    AddParameter &quot;oauth_timestamp&quot;, GetTimestamp\r\n    AddParameter &quot;oauth_token&quot;, DLookup(&quot;Token&quot;, &quot;tblApplications&quot;, &quot;ID = &quot; &amp; lngApplicationID)\r\n    AddParameter &quot;oauth_version&quot;, &quot;1.0&quot;\r\n    AddParameter &quot;oauth_consumer_key&quot;, DLookup(&quot;ConsumerKey&quot;, &quot;tblApplications&quot;, _\r\n        &quot;ID = &quot; &amp; lngApplicationID)\r\nEnd Sub<\/pre>\n<p>Diese Funktion ruft f&uuml;r jeden ben&ouml;tigten Parameter einmal eine weitere Funktion namens <b>AddParameter <\/b>auf (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-36-anchor\">Listing 3<\/a><\/span>). Diese f&uuml;gt der Tabelle <b>tblParameter <\/b>einen den &uuml;bergebenen Daten entsprechenden Datensatz hinzu.<\/p>\n<p class=\"listingueberschrift\">Listing 3: Eintragen eines Parameters in die Tabelle tblParameter<\/p>\n<pre>Public Function AddParameter(varParameter As Variant, varValue As Variant)\r\n    Dim db As DAO.Database\r\n    Set db = CurrentDb\r\n    db.Execute &quot;INSERT INTO tblParameters(Parametername, Parametervalue) VALUES (''&quot; &amp; varParameter _\r\n        &amp; &quot;'', ''&quot; &amp; varValue &amp; &quot;'')&quot;, dbFailOnError\r\n    Set db = Nothing\r\nEnd Function<\/pre>\n<p>Dabei greift <b>SetSignatureBaseParameters <\/b>teilweise auf die Daten in <b>tblApplications<\/b> zu, teilweise werden die Werte aber auch statisch zugewiesen oder dynamisch generiert. Letzteres geschieht beispielsweise beim sogenannten <b>Nonce<\/b>-Wert. Dies ist eine zuf&auml;llig generierte Zeichenfolge mit 42 Zeichen, die f&uuml;r jeden Zugriff neu erzeugt wird und somit die Eindeutigkeit auch zweier sonst identischer Authentifizierungsvorg&auml;nge gew&auml;hrleistet. Der <b>Nonce<\/b>-Wert wird durch die Funktion <b>GetOAuthNonce <\/b>erzeugt (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-44-anchor\">Listing 4<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 4: Ermitteln einer zuf&auml;lligen Zeichenfolge beliebiger L&auml;nge<\/p>\n<pre>Public Function GetOAuthNonce(intLength As Integer) As String\r\n    Dim i As Integer\r\n    Dim str As String\r\n    Const c = &quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789&quot;\r\n    For i = 1 To intLength\r\n        str = str &amp; Mid(c, Int((62 - 1 + 1) * Rnd + 1), 1)\r\n    Next i\r\n    GetOAuthNonce = str\r\nEnd Function<\/pre>\n<p>Auch der Timestamp wird durch eine eigene Funktion erzeugt, die so aussieht:<\/p>\n<pre>Public Function GetTimestamp()\r\n    GetTimestamp = DateDiff(&quot;s&quot;, &quot;1.1.1970&quot;, Now)\r\nEnd Function<\/pre>\n<p>Zur&uuml;ck zur Funktion <b>DoTwitter<\/b>: Dort wird in Zeile 15 bis 20 eine <b>For&#8230;Next<\/b>-Schleife durchlaufen, die jedes mit dem Parameter <b>strParameters <\/b>&uuml;bergebene Name\/Wert-Paar einmal durchlaufen soll. Da Name und Wert der Parameter in je einem Durchlauf bearbeitet werden sollen, enth&auml;lt das <b>For&#8230;Next<\/b>-Konstrukt den Zusatz <b>Step 2<\/b>. Innerhalb der Schleife geschehen zwei Dinge: Erstens werden die Parameter &uuml;ber die Prozedur <b>AddParameter <\/b>ebenfalls der Tabelle <b>tblParameter <\/b>zugewiesen. Zweitens wird in der Variablen <b>strParameterliste <\/b>eine Liste der Parameter erzeugt, wobei Name und Wert jeweils durch ein Gleichheitszeichen und die einzelnen Paare durch das Kaufmanns-Und voneinander getrennt werden, wobei der Wert noch URL-encodiert wird. Das erste Kaufmanns-Und vorn wird abgeschnitten, sodass ein Ausdruck wie <b>status=Neuer%20Status <\/b>dabei herauskommt.<\/p>\n<p>Die Prozedur <b>URLEncode<\/b> sieht dabei &uuml;brigens wie in <span class=\"verweis-ohneumbruch\"><a href=\"#anker-46-anchor\">Listing 5<\/a><\/span> aus. Sie durchl&auml;uft alle Zeichen der als Parameter &uuml;bergebenen Zeichenfolge und verschl&uuml;sselt alle Zeichen au&szlig;er den Buchstaben des Alphabets (klein und gro&szlig;), den Zahlen von 0 bis 9 und den Zeichen Punkt (.), Minus (-), Unterstrich (_) und Tilde (~). Dabei ermittelt sie erst den ASCII-Code, wandelt diesen in Hexadezimalcode um, erg&auml;nzt eine f&uuml;hrende Null, wenn dieser Code nur ein Zeichen enth&auml;lt, und f&uuml;gt ein f&uuml;hrendes Prozentzeichen hinzu. Aus dem Leerzeichen wird so <b>%20<\/b>, aus dem Gleichheitszeichen wird <b>%3D <\/b>und auch Umlaute und das scharfe S werden entsprechend verschl&uuml;sselt.<\/p>\n<p class=\"listingueberschrift\">Listing 5: Diese Prozedur macht Zeichenketten URL-konform.<\/p>\n<pre>Function URLEncode(StringVal As String) As String\r\n    Dim intLen As Integer\r\n    Dim i As Integer\r\n    Dim intCharCode As Integer\r\n    Dim strChar As String\r\n    Dim strTemp As String\r\n    intLen = Len(StringVal)\r\n    If intLen &gt; 0 Then\r\n        For i = 1 To intLen\r\n            strChar = Mid$(StringVal, i, 1)\r\n            intCharCode = Asc(strChar)\r\n            Select Case intCharCode\r\n                Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126\r\n                    strTemp = strTemp &amp; strChar\r\n                Case 0 To 15\r\n                    strTemp = strTemp &amp; &quot;%0&quot; &amp; Hex(intCharCode)\r\n                Case Else\r\n                    strTemp = strTemp &amp; &quot;%&quot; &amp; Hex(intCharCode)\r\n            End Select\r\n        Next i\r\n        URLEncode = strTemp\r\n    End If\r\nEnd Function<\/pre>\n<p>Danach erstellt die Funktion <b>DoTwitter <\/b>den ersten Teil der beiden Elemente, die zum Erzeugen der f&uuml;r die Authentifizierung ben&ouml;tigten Signatur gebraucht werden. Dazu f&uuml;hrt sie ab Zeile 24 die mit <b>strMethod<\/b> &uuml;bergebene Methode (POST\/GET), den URL-encodierten API-Aufruf und die nach dem Alphabet sortierte Liste der Parameter der Tabelle <b>tblParameter <\/b>zusammen. Diese liefert die Funktion <b>GetParameters<\/b> (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-47-anchor\">Listing 6<\/a><\/span>). Diese Prozedur durchl&auml;uft alle Datens&auml;tze der Tabelle <b>tblParameters<\/b> in alphabetischer Reihenfolge und f&uuml;gt die Name-Wert-Paare zu einer Zeichenkette zusammen.<\/p>\n<p class=\"listingueberschrift\">Listing 6: Diese Funktion liefert die Parameterliste f&uuml;r die Erzeugung der Signatur.<\/p>\n<pre>Public Function GetParameters() As String\r\n    Dim db As DAO.Database\r\n    Dim str As String\r\n    Dim rstParameters As DAO.Recordset\r\n    Set db = CurrentDb\r\n    Set rstParameters = db.OpenRecordset(&quot;SELECT * FROM &quot; _\r\n        &amp; &quot;tblParameters ORDER BY Parametername&quot;, dbOpenDynaset)\r\n    Do While Not rstParameters.EOF\r\n        str = str &amp; &quot;&amp;&quot; &amp; rstParameters!Parametername &amp; &quot;=&quot; _\r\n            &amp; rstParameters!ParameterValue\r\n        rstParameters.MoveNext\r\n    Loop\r\n    If Left(str, 1) = &quot;&amp;&quot; Then\r\n        str = Mid(str, 2)\r\n    End If\r\n    GetParameters = str\r\nEnd Function<\/pre>\n<p>In Zeile 25 stellt <b>DoTwitter <\/b>dann den Schl&uuml;ssel zum Signieren zusammen. Dieser besteht aus den Werten f&uuml;r <b>ConsumerSecret <\/b>und <b>TokenSecret <\/b>der Tabelle <b>tblApplications<\/b>. Die Signatur wird dann schlie&szlig;lich durch die Funktion <b>GetSignature<\/b> ermitteln (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-48-anchor\">Listing 7<\/a><\/span>). Diese Prozedur verwendet mehrere Methoden der Klasse <b>clsHMACSHA1<\/b>, die wir [1] entnommen haben.<\/p>\n<p class=\"listingueberschrift\">Listing 7: GetSignature liefert die Signatur f&uuml;r die Authentifizierung.<\/p>\n<pre>Public Function GetSignature(strData As String, strKey As String) As String\r\n    Dim objHMACSHA1 As clsHMACSHA1\r\n    Dim bytSig() As Byte\r\n    Set objHMACSHA1 = New clsHMACSHA1\r\n    With objHMACSHA1\r\n        .InitHmac .Decode(StringToHex(strKey))\r\n        bytSig = .HmacSha1(.Decode(StringToHex(strData)))\r\n        GetSignature = URLEncode(Encode64(HexToText(.Encode(bytSig))))\r\n    End With\r\nEnd Function<\/pre>\n<p>Zun&auml;chst wird der Schl&uuml;ssel mit der Funktion <b>StringToHex <\/b>(s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-49-anchor\">Listing 8<\/a><\/span>) in hexadezimale ASCII-Werte umgewandelt (<b>A <\/b>wird so &uuml;ber den ASCII-Code <b>65 <\/b>zu <b>41<\/b>). Daraus erzeugt die Methode <b>Decode <\/b>der Klasse <b>clsHMACSHA1 <\/b>ein Byte-Array f&uuml;r die weitere Verarbeitung durch die Methode <b>InitHMAC<\/b>.<\/p>\n<p class=\"listingueberschrift\">Listing 8: Umwandeln eines Textes in hexadezimale ASCII-Codes<\/p>\n<pre>Public Function StringToHex(str As String) As String\r\n    Dim i As Integer\r\n    Dim strTemp As String\r\n    For i = 1 To Len(str)\r\n        strTemp = strTemp &amp; Hex(Asc(Mid(str, i, 1)))\r\n    Next i\r\n    StringToHex = strTemp\r\nEnd Function<\/pre>\n<p>Danach wird die Parameterliste auf die gleiche Weise mit <b>StringToHex <\/b>und <b>Decode <\/b>behandelt und dann der Funktion <b>HmacSha1 <\/b>&uuml;bergeben, die das Ergebnis als Byte-Array zur&uuml;ckliefert. Nach der Behandlung mit den drei Funktionen <b>Encode<\/b>, <b>HexToText<\/b>, <b>Encode64 <\/b>und <b>URLEncode <\/b>erhalten wir die Signatur im gew&uuml;nschten Format.<\/p>\n<p>Die hier verwendete Funktion <b>HexToText<\/b> wandelt mithilfe einer weiteren Funktion namens <b>HexToDec <\/b>hexadezimale ASCII-Codes wieder in Zeichen um (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-51-anchor\">Listing 9<\/a><\/span> und <span class=\"verweis-ohneumbruch\"><a href=\"#anker-52-anchor\">Listing 10<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 9: Text aus hexadezimalem ASCII-Code erzeugen<\/p>\n<pre>Public Function HexToText(strSignature) As String\r\n    Dim str As String\r\n    Dim intCount As Integer\r\n    Dim strValue As String\r\n    For intCount = 0 To 19\r\n        strValue = Mid(strSignature, 1 + (intCount * 2), 2)\r\n        str = str &amp; Chr(HexToDec(strValue))\r\n    Next\r\n    HexToText = str\r\nEnd Function<\/pre>\n<p class=\"listingueberschrift\">Listing 10: Hexadezimale Werte in dezimale Werte umwandeln<\/p>\n<pre>Function HexToDec(strValue As String) As String\r\n    Dim strChars As String\r\n    Dim intValue As Integer\r\n    Dim intLen As Integer\r\n    Dim strChar As String\r\n    Dim intPosition As Integer\r\n    Dim i As Integer\r\n    intValue = UCase(intValue)\r\n    strChars = &quot;0123456789ABCDEF&quot;\r\n    intValue = 0\r\n    intLen = Len(strValue)\r\n    For i = 1 To intLen\r\n        strChar = Mid(strValue, i, 1)\r\n        intPosition = InStr(strChars, strChar) - 1\r\n        intValue = intValue + (intPosition * (16 ^ (intLen - i)))\r\n    Next\r\n    HexToDec = intValue\r\nEnd Function<\/pre>\n<p>Erstere ermittelt dabei jeweils die Paare der Werte zwischen <b>00 <\/b>und <b>FF <\/b>und gibt diese an die Funktion <b>HexToDec <\/b>weiter, welche diese in Zahlen von <b>0 <\/b>bis <b>255 <\/b>umwandelt. Den ganzen Zirkus haben wir nur veranstaltet, um an diese Signatur zu kommen. Diese f&uuml;gt die Funktion <b>GetOAuthHeader <\/b>nun zu Headerdaten zusammen (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-53-anchor\">Listing 11<\/a><\/span>).<\/p>\n<p class=\"listingueberschrift\">Listing 11: Ermitteln der Headerdaten<\/p>\n<pre>Public Function GetOAuthHeader(strSignature As String, strAction As String) As String\r\n    Dim str As String\r\n    str = &quot;OAuth realm=&quot; &amp; Chr(34) &amp; strAction &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_nonce=&quot; &amp; Chr(34) &amp; DLookup(&quot;ParameterValue&quot;, &quot;tblParameters&quot;, _\r\n        &quot;Parametername = ''Oauth_nonce''&quot;) &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_signature_method=&quot; &amp; Chr(34) &amp; &quot;HMAC-SHA1&quot; &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_timestamp=&quot; &amp; Chr(34) &amp; DLookup(&quot;ParameterValue&quot;, &quot;tblParameters&quot;, _\r\n        &quot;Parametername = ''oauth_timestamp''&quot;) &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_consumer_key=&quot; &amp; Chr(34) &amp; DLookup(&quot;ParameterValue&quot;, &quot;tblParameters&quot;, _\r\n        &quot;Parametername = ''Oauth_consumer_key''&quot;) &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_token=&quot; &amp; Chr(34) &amp; DLookup(&quot;ParameterValue&quot;, &quot;tblParameters&quot;, _\r\n        &quot;Parametername = ''Oauth_token''&quot;) &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_signature=&quot; &amp; Chr(34) &amp; strSignature &amp; Chr(34)\r\n    str = str &amp; &quot;, oauth_version=&quot; &amp; Chr(34) &amp; &quot;1.0&quot; &amp; Chr(34)\r\n    GetOAuthHeader = str\r\nEnd Function<\/pre>\n<p>Diese Daten, die zusammen mit der HTTP-Anfrage zur Authentifizierung an Twitter gesendet werden, sehen etwa so aus:<\/p>\n<pre>OAuth realm=&quot;http:\/\/api.twitter.com\/1\/statuses\/update.xml&quot;, oauth_nonce=&quot;g9PaJggXrabcs68yrjkOzzSuNmlKfC4qWxr5NMAg&quot;, \r\noauth_signature_method=&quot;HMAC-SHA1&quot;, oauth_timestamp=&quot;1309296231&quot;, \r\noauth_consumer_key=&quot;W1wBuWOeTesndKsZKaBgfg&quot;, oauth_token=&quot;78842002-cOj7O8MOOUI07WP4Oam8SSNc5cb7W9tmyEvstcRw&quot;, \r\noauth_signature=&quot;pFkleVGPqPT3Oacn4asIpTcy4hQ%3D&quot;, oauth_version=&quot;1.0&quot;<\/pre>\n<p>Mit diesen Informationen im Gep&auml;ck geht es an die eigentliche Kontaktaufnahme mit Twitter.<\/p>\n<p>Das <b>XMLHTTP<\/b>-Objekt erm&ouml;glicht es, die Anfrage unter Angabe der Header-Daten an Twitter zu senden. Dabei geben Sie die Methode (<b>POST<\/b>\/<b>GET<\/b>) und die URL mit Parameterliste als Parameter der <b>Open<\/b>-Methode an und die Headerdaten als Parameter der Methode <b>setRequestHeader<\/b>.<\/p>\n<p>Nach dem Ausf&uuml;hren der <b>send<\/b>-Methode enth&auml;lt die Eigenschaft <b>responseText <\/b>die Antwort von Twitter. Diese packen wir in ein XML-Dokument und geben diese als Funktionswert von <b>DoTwitter<\/b> an die aufrufende Funktion zur&uuml;ck.<\/p>\n<p><b>Twitter-Aufruf im Einsatz<\/b><\/p>\n<p>Fehlen noch die Bindeglieder zwischen den Schaltfl&auml;chen des Formulars <b>frmTwittern<\/b> und der Funktion <b>DoTwitter<\/b>. Die Prozedur hinter der Schaltfl&auml;che zum Aktualisieren der Statusmeldung etwa ruft die Funktion <b>NeuerStatus <\/b>auf (s. <span class=\"verweis-ohneumbruch\"><a href=\"#anker-54-anchor\">Listing 12<\/a><\/span>). Diese legt die Methode (<b>POST <\/b>als <b>strMethode<\/b>) und die URL fest (<b>http:\/\/api.twitter.com\/1\/statuses\/update.xml <\/b>als <b>strAction<\/b>).<\/p>\n<p class=\"listingueberschrift\">Listing 12: Aktualisieren der Statusmeldung<\/p>\n<pre>Public Function NeuerStatus(lngID As Long, strStatus As String) As String\r\n    Dim objXML As MSXML2.DOMDocument\r\n    Dim strAction As String\r\n    Dim strMethod As String\r\n    strAction = &quot;http:\/\/api.twitter.com\/1\/statuses\/update.xml&quot;\r\n    strMethod = &quot;POST&quot;\r\n    Set objXML = DoTwitter(lngID, strAction, strMethod, &quot;status&quot;, strStatus)\r\n    On Error Resume Next\r\n    NeuerStatus = objXML.selectSingleNode(&quot;status\/id&quot;).nodeTypedValue\r\n    If Not Err.Number = 0 Then\r\n        On Error GoTo 0\r\n        MsgBox &quot;Fehler: &quot; &amp; objXML.selectSingleNode(&quot;hash\/error&quot;).nodeTypedValue\r\n    End If\r\nEnd Function<\/pre>\n<p>Dann ruft sie die Funktion <b>DoTwitter <\/b>mit dem Parameternamen <b>status <\/b>und der Statusmeldung als weitere Parameter auf und weist das Ergebnis der als <b>DOMDocument <\/b>deklarierten Variablen <b>objXML <\/b>zu.<\/p>\n<p>Das Ergebnis sieht beispielsweise wie in <span class=\"verweis-ohneumbruch\"><a href=\"#anker-55-anchor\">Listing 13<\/a><\/span> aus.<\/p>\n<p class=\"listingueberschrift\">Listing 13: XML-Antwort auf das Aktualisieren der Statusmeldung<\/p>\n<pre>&lt;status&gt;\r\n    &lt;created_at&gt;Tue Jun 28 19:44:51 +0000 2011&lt;\/created_at&gt;\r\n    &lt;id&gt;85795816740106241&lt;\/id&gt;\r\n    &lt;text&gt;Neuer Status&lt;\/text&gt;\r\n    ...\r\n    &lt;user&gt;\r\n        &lt;id&gt;78842002&lt;\/id&gt;\r\n        &lt;name&gt;Andr&eacute; Minhorst&lt;\/name&gt;\r\n        &lt;screen_name&gt;andreminhorst&lt;\/screen_name&gt;\r\n        &lt;location&gt;Duisburg&lt;\/location&gt;\r\n    ...\r\n    &lt;\/user&gt;\r\n    ...\r\n&lt;\/status&gt;<\/pre>\n<p>Es liefert nicht nur die ID der neuen Statusmeldung, sondern auch noch einige weitere Informationen zur&uuml;ck, unter anderem auch &uuml;ber den Benutzer, der die Statusmeldung gesendet hat. Die Funktion <b>NeuerStatus <\/b>versucht, den Wert des Elements <b>status\/id <\/b>auszulesen, um die ID der neuen Statusmeldung zu ermitteln. Gelingt dies, wird der Wert als Ergebnis der Funktion zur&uuml;ckgegeben. Wenn beim Senden der Statusmeldung ein Problem aufgetreten ist, sieht das von Twitter gelieferte XML-Dokument beispielsweise wie folgt aus:<\/p>\n<pre>&lt;hash&gt;\r\n    &lt;error&gt;Status is a duplicate.&lt;\/error&gt;\r\n    &lt;request&gt;\/1\/statuses\/update.xmlstatus=Neuer%20Status&lt;\/request&gt;\r\n&lt;\/hash&gt;<\/pre>\n<p>Hier wurde offensichtlich versucht, eine bereits vorhandene Statusmeldung erneut zu senden. In diesem Fall l&ouml;st der Zugriff auf das nicht vorhandene Element <b>status\/id <\/b>einen Fehler aus, was automatisch dazu f&uuml;hrt, dass die Funktion den Wert des Elements <b>hash\/error <\/b>ausliest, hier also <b>Status is a duplicate<\/b>.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Es ist schon faszinierend, was sich mit Access alles erledigen l&auml;sst. Leider ist die Programmierung von L&ouml;sungen wie dieser sehr aufwendig, da gerade Codebeispiele f&uuml;r den Zugriff auf Webanwendungen wie Twitter, Amazon, eBay und Co. eher mit Programmiersprachen wie PHP, Java oder einem der .NET-Dialekte erledigt werden. Dort gibt es Bibliotheken, die Aufgaben wie das Ermitteln einer HMAC-SHA1-Signatur in Form fertiger Funktionen anbieten. Umso sch&ouml;ner, dass es immer noch Entwickler gibt, die solche Funktionen nachbauen und somit die Grundlage f&uuml;r Beitr&auml;ge wie diesen liefern.<\/p>\n<p class=\"zwischen-berschriftquellen\">Quellen<\/p>\n<p class=\"quellen\">[1] Klasse mit HMAC_SHA1-Erzeugung: http:\/\/www.vbforums.com\/showpost.phpp=3996113&amp;postcount=4<\/p>\n<p class=\"quellen\">[2] Oauth mit Excel: http:\/\/www.twopblog.com\/2010\/09\/using-excel-as-twitter-client-with.html<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>TwitterOAuth.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{7E861657-B698-4B9D-AA06-742FC3353BE6}\/aiu_790.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Mit dem Automatisieren des Webdienstes Twitter hat Access im Unternehmen sich bereits besch&auml;ftigt. Allerdings hat Twitter mittlerweile die Authentifizierungsmethode gewechselt &#8211; auf das sogenannte OAuth. Die Programmierung des Zugriffs ist nicht ganz trivial, vor allem wegen der Erzeugung des notwendigen HMAC-SHA1-Ausdrucks, der zur Authentifizierung der Anfrage dient. Wie dies gel&ouml;st wurde und wie der Zugriff auf Twitter nun funktioniert, erfahren Sie in diesem Beitrag.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662011,66042011,44000026],"tags":[],"class_list":["post-55000790","post","type-post","status-publish","format-standard","hentry","category-662011","category-66042011","category-Interaktiv"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Authentifizieren mit OAuth am Beispiel von Twitter - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Authentifizieren mit OAuth am Beispiel von Twitter\" \/>\n<meta property=\"og:description\" content=\"Mit dem Automatisieren des Webdienstes Twitter hat Access im Unternehmen sich bereits besch&auml;ftigt. Allerdings hat Twitter mittlerweile die Authentifizierungsmethode gewechselt - auf das sogenannte OAuth. Die Programmierung des Zugriffs ist nicht ganz trivial, vor allem wegen der Erzeugung des notwendigen HMAC-SHA1-Ausdrucks, der zur Authentifizierung der Anfrage dient. Wie dies gel&ouml;st wurde und wie der Zugriff auf Twitter nun funktioniert, erfahren Sie in diesem Beitrag.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T21:57:16+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"25\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Authentifizieren mit OAuth am Beispiel von Twitter\",\"datePublished\":\"2020-05-22T21:57:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/\"},\"wordCount\":3565,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/2924cea21f6741e49423093d2483c1a4\",\"articleSection\":[\"2011\",\"4\\\/2011\",\"Interaktiv\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/\",\"name\":\"Authentifizieren mit OAuth am Beispiel von Twitter - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/2924cea21f6741e49423093d2483c1a4\",\"datePublished\":\"2020-05-22T21:57:16+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/2924cea21f6741e49423093d2483c1a4\",\"contentUrl\":\"http:\\\/\\\/vg01.met.vgwort.de\\\/na\\\/2924cea21f6741e49423093d2483c1a4\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Authentifizieren mit OAuth am Beispiel von Twitter\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Authentifizieren mit OAuth am Beispiel von Twitter - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/","og_locale":"de_DE","og_type":"article","og_title":"Authentifizieren mit OAuth am Beispiel von Twitter","og_description":"Mit dem Automatisieren des Webdienstes Twitter hat Access im Unternehmen sich bereits besch&auml;ftigt. Allerdings hat Twitter mittlerweile die Authentifizierungsmethode gewechselt - auf das sogenannte OAuth. Die Programmierung des Zugriffs ist nicht ganz trivial, vor allem wegen der Erzeugung des notwendigen HMAC-SHA1-Ausdrucks, der zur Authentifizierung der Anfrage dient. Wie dies gel&ouml;st wurde und wie der Zugriff auf Twitter nun funktioniert, erfahren Sie in diesem Beitrag.","og_url":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T21:57:16+00:00","og_image":[{"url":"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"25\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Authentifizieren mit OAuth am Beispiel von Twitter","datePublished":"2020-05-22T21:57:16+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/"},"wordCount":3565,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4","articleSection":["2011","4\/2011","Interaktiv"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/","url":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/","name":"Authentifizieren mit OAuth am Beispiel von Twitter - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#primaryimage"},"thumbnailUrl":"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4","datePublished":"2020-05-22T21:57:16+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#primaryimage","url":"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4","contentUrl":"http:\/\/vg01.met.vgwort.de\/na\/2924cea21f6741e49423093d2483c1a4"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Authentifizieren_mit_OAuth_am_Beispiel_von_Twitter\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Authentifizieren mit OAuth am Beispiel von Twitter"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000790","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000790"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000790\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000790"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000790"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000790"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}