Actualizarea Twitter din baza de date, folosind PL / SQL si OAuth.

 Trimiterea actualizarilor catre Twitter din baza de date a fost foarte usoara atunci cand Twitter sprijina inca autentificarea de baza. O postare simpla HTTP si ai terminat. Cu toate acestea, deoarece OAuthcalypse acest lucru nu mai este posibil. In zilele noastre, OAuth este folosit pentru a se autentifica cu twitter si au disparut zilele usoare.

Am reusit sa actualizez starea Twitter de la Oracle 10g XE folosind OAuth, scris complet in PL / SQL. Aceasta postare descrie cum se face. Am urmat acest ghid si am folosit biti de cod din aceasta postare (criptica). Urmati ghidul mentionat, impreuna cu esantioanele de cod pentru a intelege fiecare pas.

Voi folosi modul de autorizare in afara bandei , care este mai usor si nu implica apelul de autorizare.

Pentru a utiliza un client pentru a actualiza cronologia utilizatorului Twitter, vom avea permisiunea utilizatorului sa faca acest lucru. Aceasta inseamna ca programul client trebuie autorizat.

Aplicatia client

In primul rand, cererea client trebuie inregistrata. Acest lucru se poate face aici. Veti obtine cheia consumatorului si secretul consumatorului .

Cele elementare

Iata despre ce este vorba: pentru comunicarea cu Twitter, sunt practic patru lucruri de facut:

  1. Creati un sir de baza semnatura;
  2. Folositi-o pentru a crea o semnatura OAuth;
  3. Creati un antet HTTP de autorizare;
  4. Efectuati un HTTP POST catre API-ul specific.

Partea I: primirea jetonului cererii

Codul pe care il vedeti mai jos face doar asta. Retineti utilizarea DBMS_CRYPTO. Asigurati-va ca aveti drepturi de executie asupra pachetului respectiv! De asemenea, completati detaliile dvs. acolo unde este necesar si infrumusetati acolo unde este necesar 🙂

Pentru codare URL, am folosit cateva pachete pe care le-am gasit pe web. Cumva nu am putut gasi o functie existenta in baza de date pentru asta.

creati sau inlocuiti functia urlencode (p_str in varchar2) return varchar2 as / * FROM: http://www.orafaq.com/forum/t/48047/0/ * POSITATE DE UTILIZATOR: http://www.orafaq.com/ forum / u / 45693/0 / * KUDOS! * / l_tmp varchar2 (6000); l_bad varchar2 (100) implicit ‘>%} \ ~];? @ & <# {| ^ [`/: = $ +’ ‘”‘; l_char char (1); incepe pentru i in 1 .. nvl (lungime (p_str), 0) bucla l_char: = substr (p_str, i, 1); daca (instr (l_bad, l_char)> 0) atunci l_tmp: = l_tmp || ‘%’ || to_char (ascii (l_char), ‘ fmXX ‘); altfel l_tmp: = l_tmp || l_char; sfarsit daca; bucla finala; intoarcere l_tmp; final;

/ * Obtineti tokenul cererii pentru autorizarea Twitter * Veti avea nevoie de mai mult decat acest fisier sursa singur! Verificati blogul * pentru detalii! * * De: Identitatea secreta a SomeCodingHero: Laurens van der Starre. * Blog: http://somecodinghero.blogspot.

Array

com/ * Twiitter: somecodinghero * Codul este GPL. Sper ca va va fi de folos. * / SET SERVEROUTPUT PE DECLARE l_oauth_request_token_url CONSTANT VARCHAR2 (500): = ‘http://api.twitter.com/oauth/request_token’; l_oauth_consumer_key CONSTANT VARCHAR2 (500): = ‘your_consumer_key’; l_oauth_nonce VARCHAR2 (500); l_oauth_signature_method CONSTANT VARCHAR2 (10): = urlencode (‘HMAC-SHA1’); l_oauth_timestamp VARCHAR2 (100); l_oauth_version CONSTANT VARCHAR2 (5): = urlencode (‘1.0’); l_oauth_consumer_secret CONSTANT VARCHAR2 (500): = ‘your_consumer_secret’; l_oauth_callback CONSTANT VARCHAR2 (5): = ‘oob’; l_http_method VARCHAR2 (5): = ‘POST’; l_oauth_base_string VARCHAR2 (2000); l_oauth_key VARCHAR2 (500): = l_oauth_consumer_secret || ‘&’; l_sig_mac RAW (2000); l_base64_sig_mac VARCHAR2 (100); http_req UTL_HTTP.req; http_resp UTL_HTTP.resp; l_update_send VARCHAR2 (2000); l_oauth_header VARCHAR2 (2000); l_line VARCHAR2 (1024); resp_name VARCHAR2 (256); resp_value VARCHAR2 (1024); l_random varchar2 (15); BEGIN – RANDOM oauth_nonce SELECT dbms_random.string (‘A’, 15) INTO l_random FROM DUAL; SELECT urlencode (UTL_ENCODE.base64_encode (UTL_I18N.string_to_raw (l_random, ‘AL32UTF8’)))) INTO l_oauth_nonce FROM DUAL; – Obtineti marcajul de timp SELECT urlencode ((SYSDATE – TO_DATE (’01 -01-1970 ‘,’ DD-MM-AAAA ‘)) * (86400)) – 7200 INTO l_oauth_timestamp FROM DUAL; – Creati sirul de baza l_oauth_base_string: = l_http_method || „&” || urlencode (l_oauth_request_token_url) || „&” || urlencode (‘oauth_callback’ || ‘=’ || l_oauth_callback || ‘&’ || ‘oauth_consumer_key’ || ‘=’ || l_oauth_consumer_key || ‘&’ || ‘oauth_nonce’ || ‘=’ || l_oauth_nonce | | ‘&’ || ‘oauth_signature_method’ || ‘=’ || l_oauth_signature_method || ‘&’ || ‘oauth_timestamp’ || ‘=’ || l_oauth_timestamp || ‘&’ || ‘oauth_version’ || ‘=’ || l_oauth_version); DBMS_OUTPUT.put_line (l_oauth_base_string); – Creati semnatura oauth l_sig_mac: = DBMS_CRYPTO.mac (UTL_I18N.string_to_raw (l_oauth_base_string, ‘AL32UTF8’), DBMS_CRYPTO.hmac_sh1, UTL_I18N. string_to_raw (l_oauth_key, ‘AL32UTF8’)); l_base64_sig_mac: = UTL_RAW.cast_to_varchar2 (UTL_ENCODE.base64_encode (l_sig_mac)); DBMS_OUTPUT.put_line (‘Semnatura MAC (bazata pe 64):’ || l_base64_sig_mac); – URL-ul „actualizare” pentru utilizarea API-ului. l_update_send: = l_oauth_request_token_url || ‘?’ || „oauth_callback” || ‘=’ || l_oauth_callback || „&” || „oauth_consumer_key” || ‘=’ || l_oauth_consumer_key || „&” || „oauth_nonce” || ‘=’ || l_oauth_nonce || „&” || „oauth_signature” || ‘=’ || urlencode (l_base64_sig_mac) || „&” || „oauth_signature_method” || ‘=’ || l_oauth_signature_method || „&” || „oauth_timestamp” || ‘=’ || l_oauth_timestamp || „&” || ‘ oauth_version ‘|| ‘=’ || l_oauth_version; http_req: = UTL_HTTP.begin_request (l_update_send, l_http_method, UTL_HTTP.http_version_1_1); DBMS_OUTPUT.put_line (‘UPDATE URL’ || l_update_send); UTL_HTTP.set_response_error_check (TRUE); UTL_HTTP.set_detailed_excp_support (TRUE); – Antetul autorizatiei. Retineti partea „Autorizare:”. Lasa-l si – nu va functiona ..

. l_oauth_header: = ‘Autorizare: OAuth oauth_nonce = „‘ || l_oauth_nonce || ‘”,’ || ‘oauth_callback = „‘ || l_oauth_callback || ‘”,’ || ‘oauth_signature_method = „‘ || l_oauth_signature_method || ‘”,’ || ‘oauth_timestamp = „‘ || l_oauth_timestamp || ‘”,’ || ‘oauth_consumer_key = „‘ || l_oauth_consumer_key || ‘”,’ || ‘ oauth_signature = „‘|| urlencode (l_base64_sig_mac) ||'”, ‘|| ‘oauth_version = „‘ || l_oauth_version || ‘”‘; utl_http.set_header (r => http_req, NAME => ‘Autorizare’, VALUE => l_oauth_header); DBMS_OUTPUT.put_line (‘HEADER:’ || l_oauth_header); utl_http.write_text (r => http_req, DATA => ”); http_resp: = utl_http.get_response (r => http_req); – Obtineti rezultatul. Aceasta iesire contine secretul auth_token si auth_token – necesare pentru trimiterea autorizatiei! DBMS_OUTPUT.put_line (‘OBTINERE RASPUNSURI DE RASPUNS!’); FOR i IN 1..utl_http.get_header_count (http_resp) LOOP utl_http.get_header (http_resp, i, resp_name, resp_value); dbms_output.put_line (resp_name || ‘:’ || resp_value); CAMPUL FINAL; DBMS_OUTPUT.put_line (‘Obtinere de continut:’); BEGIN LOOP utl_http.read_line (http_resp, resp_value, TRUE); dbms_output.put_line (resp_value); CAMPUL FINAL; EXCEPTION WHEN utl_http.end_of_body THEN DBMS_OUTPUT.put_line (‘Nu mai exista continut.’); SFARSIT; utl_http.end_response (r => http_resp); EXCEPTION cand altii apoi DBMS_OUTPUT.put_line (‘EROARE HTTP:’ || utl_http.get_detailed_sqlerrm); SFARSIT; 

In raspuns va fi secretul oauth-token si auth-token-secret. Salvati-le deocamdata, pentru ca avem nevoie de ele pentru a obtine simbolul de acces.

Retineti ca folosim metoda Out of Band (consultati „oob” pentru oauth_callback)!

Partea a II-a: obtinerea tokenului de acces

Indicati utilizatorul (Twitter) catre http://api.twitter.com/oauth/authorize?oauth_token= __your_received_oauth_token___ . Utilizatorul Twitter trebuie sa acorde acces la aplicatia pentru consumatori. Cand reuseste, va fi afisat un cod PIN (deoarece folosim metoda Out of Band). Retineti acest lucru in jos, deoarece acesta este oauth_verifier .

/ * Obtineti tokenul cererii pentru autorizarea utilizatorului Twitter * Veti avea nevoie de mai mult decat acest fisier sursa singur! Verificati blogul * pentru detalii! * * De: Identitatea secreta a SomeCodingHero: Laurens van der Starre. * Blog: http://somecodinghero.blogspot.com/ * Twiitter: somecodinghero * Codul este GPL. Sper ca va va fi de folos. * / DECLARE l_oauth_request_token_url CONSTANT VARCHAR2 (500): = ‘http://api.twitter.com/oauth/access_token’; l_oauth_consumer_key CONSTANT VARCHAR2 (500): = ‘cheie_ consumator’; l_oauth_token CONSTANT VARCHAR2 (500): = ‘oauth_token’; l_oauth_secret CONSTANT VARCHAR2 (500): = ‘oauth_secret’; l_oauth_nonce VARCHAR2 (500); l_oauth_signature_method CONSTANT VARCHAR2 (10): = urlencode (‘HMAC-SHA1’); l_oauth_timestamp VARCHAR2 (100); l_oauth_version CONSTANT VARCHAR2 (5): = urlencode (‘1. 0’ ); l_oauth_consumer_secret CONSTANT VARCHAR2 (500): = ‘consumator_secret’; l_http_method VARCHAR2 (5): = ‘POST’; l_oauth_base_string VARCHAR2 (2000); l_oauth_key VARCHAR2 (500): = l_oauth_consumer_secret || ‘&’ l_oauth_secret; l_sig_mac RAW (2000); l_base64_sig_mac VARCHAR2 (100); http_req UTL_HTTP.req; http_resp UTL_HTTP.resp; l_update_send VARCHAR2 (2000); l_oauth_header VARCHAR2 (2000); l_line VARCHAR2 (1024); resp_name VARCHAR2 (256); resp_value VARCHAR2 (1024); l_oob_pin VARCHAR (10): = ‘PIN NR’; l_random varchar2 (15); BEGIN – RANDOM oauth_nonce SELECT dbms_random.string (‘A’, 15) INTO l_random FROM DUAL; SELECT urlencode (UTL_ENCODE.base64_encode (UTL_I18N.string_to_raw (l_random, ‘AL32UTF8’)))) INTO l_oauth_nonce FROM DUAL; SELECT urlencode ((SYSDATE – TO_DATE (’01 -01-1970 ‘,’) DD-MM-AAAA ‘)) * (86400)) – 7200 INTO l_oauth_timestamp din DUAL; l_oauth_base_string: = l_http_method || „&” || urlencode (l_oauth_request_token_url) || „&” || urlencode (‘oauth_consumer_key’ || ‘=’ || l_oauth_consumer_key || ‘&’ || ‘oauth_nonce’ || ‘=’ || l_oauth_nonce || ‘&’ || ‘oauth_signature_method’ || ‘=’ || l_oauth_signature_method | | ‘&’ || ‘oauth_timestamp’ || ‘=’ || l_oauth_timestamp || ‘&’ || ‘oauth_token’ || ‘=’ || l_oauth_token || ‘&’ || ‘oauth_verifier’ || ‘=’ || l_oob_pin || ‘&’ || ‘oauth_version’ || ‘=’ || l_oauth_version); DBMS_OUTPUT.put_line (l_oauth_base_string); l_sig_mac: = DBMS_CRYPTO.mac (UTL_I18N. string_to_raw (l_oauth_base_string, ‘AL32UTF8’), DBMS_CRYPTO.hmac_sh1, UTL_I18N.string_to_raw (l_oauth_key, ‘AL32UTF8’)); DBMS_OUTPUT.put_line (‘Sig combinate:’ || l_oauth_key || l_oauth_secret); l_base64_sig_mac: = UTL_RAW.cast_to_varchar2 (UTL_ENCODE.base64_encode (l_sig_mac)); DBMS_OUTPUT.put_line (‘Semnatura MAC (bazata pe 64):’ || l_base64_sig_mac); l_update_send: = l_oauth_request_token_url || ‘?’ || „oauth_consumer_key” || ‘=’ || l_oauth_consumer_key || „&” || „oauth_nonce” || ‘=’ || l_oauth_nonce || „&” || „oauth_signature_method” || ‘=’ || l_oauth_signature_method || „&” || „oauth_timestamp” || ‘=’ || l_oauth_timestamp || „&” || „oauth_token” || ‘=’ || l_oauth_token || „&” || „oauth_verifier” || ‘=’ || l_oob_pin || „&” || „oauth_version” || ‘=’ || l_oauth_version; http_req: = UTL_HTTP.begin_request (l_update_send, l_http_method, UTL_HTTP.http_version_1_1); DBMS_OUTPUT.put_line (‘UPDATE URL’ || l_update_send); UTL_HTTP.set_response_error_check (TRUE); UTL_HTTP.set_detailed_excp_support (TRUE); l_oauth_header: = ‘Autorizare: OAuth oauth_nonce = „‘ || l_oauth_nonce || ‘”,’ || ‘oauth_signature_method = „‘ || l_oauth_signature_method || ‘”,’ || ‘oauth_timestamp = „‘ || l_oauth_timestamp || ‘”,’ || ‘oauth_consumer_key = „‘ || l_oauth_consumer_key || ‘”,’ || ‘oauth_token = „‘ || l_oauth_token || ‘”,’ || ‘ oauth_verifier = „‘|| l_oob_pin ||'”, ‘|| ‘oauth_signature = „‘ || urlencode (l_base64_sig_mac) || ​​'”,’ || ‘oauth_version = „‘ || l_oauth_version || ‘”‘; utl_http.set_header (r => http_req, NAME => ‘Autorizare’, VALUE => l_oauth_header); DBMS_OUTPUT.put_line (‘HEADER:’ || l_oauth_header); utl_http.write_text (r => http_req, DATA => ”); http_resp: = utl_http.get_response (r => http_req); DBMS_OUTPUT.put_line (‘OBTINERE RASPUNSURI DE RASPUNS!’); FOR i IN 1..utl_http.get_header_count (http_resp) LOOP utl_http.get_header (http_resp, i, resp_name, resp_value); dbms_output.put_line (resp_name || ‘:’ || resp_value); CAMPUL FINAL; DBMS_OUTPUT.put_line (‘Obtinere de continut:’); BEGIN LOOP utl_http.read_line (http_resp, resp_value, ADEVARAT); dbms_output.put_line (resp_value); CAMPUL FINAL; EXCEPTION WHEN utl_http.end_of_body THEN DBMS_OUTPUT.put_line (‘Nu mai exista continut.’); SFARSIT; utl_http.end_response (r => http_resp); EXCEPTION cand altii apoi DBMS_OUTPUT.put_line (‘EROARE HTTP:’ || utl_http.get_detailed_sqlerrm); SFARSIT;

(Vezi ca codul este cam acelasi). Acum ai primit tokenul de acces. Salvati acestea. Acestea vor fi utilizate pentru actualizarile de stare Twitter.

Partea a III-a: realizarea unei actualizari a starii

Acum avem tokenul de acces efectiv. Acest jeton este folosit pentru a face lucrurile in numele utilizatorului Twitter.

Trimiterea unui tweet de exemplu (cod deja-vu :-)):

SETA SERVEROUTPUT PE DECLARE l_oauth_request_token_url CONSTANT VARCHAR2 (500): = ‘http://api.twitter.com/1/statuses/update.xml’; l_oauth_consumer_key CONSTANT VARCHAR2 (500): = ‘cheie_ consumator’; l_oauth_token CONSTANT VARCHAR2 (500): = ‘ACCES TOKEN’; l_oauth_secret CONSTANT VARCHAR2 (500): = ‘SECRET TOKEN ACCES’; l_oauth_nonce VARCHAR2 (500); l_oauth_signature_method CONSTANT VARCHAR2 (10): = urlencode (‘HMAC-SHA1’); l_oauth_timestamp VARCHAR2 (100); l_oauth_version CONSTANT VARCHAR2 (5): = urlencode (‘1.0’); l_oauth_consumer_secret CONSTANT VARCHAR2 (500): = ‘SECRET DE CONSUM’; l_http_method VARCHAR2 (5): = ‘POST’; l_oauth_base_string VARCHAR2 (2000); l_oauth_key VARCHAR2 (500): = l_oauth_consumer_secret || „&” || l_oauth_secret; l_sig_mac RAW (2000); l_base64_sig_mac VARCHAR2 (100); http_req UTL_HTTP.req; http_resp UTL_HTTP.resp; l_update_send VARCHAR2 (2000); l_oauth_header VARCHAR2 (2000); l_line VARCHAR2 (1024); resp_name VARCHAR2 (256); resp_value VARCHAR2 (1024); l_content varchar2 (140): = urlencode (‘@ somecodinghero You rule !! :-)’); l_random varchar2 (15); BEGIN – RANDOM oauth_nonce SELECT dbms_random.string (‘A’, 15) INTO l_random FROM DUAL; SELECT urlencode (UTL_ENCODE.base64_encode (UTL_I18N.string_to_raw (l_random, ‘AL32UTF8’)))) INTO l_oauth_nonce FROM DUAL; l_oauth_base_string: = l_http_method || „&” || urlencode (l_oauth_request_token_url) || „&” || urlencode (‘oauth_consumer_key’ || ‘=’ || l_oauth_consumer_key || ‘&’ || ‘oauth_nonce’ || ‘=’ || l_oauth_nonce || ‘&’ || ‘ oauth_signature_method ‘|| ‘=’ || l_oauth_signature_method || „&” || „oauth_timestamp” || ‘=’ || l_oauth_timestamp || „&” || „oauth_token” || ‘=’ || l_oauth_token || „&” || „oauth_version” || ‘=’ || l_oauth_version || „&” || „statut” || ‘=’ || l_content); DBMS_OUTPUT.put_line (l_oauth_base_string); l_sig_mac: = DBMS_CRYPTO.mac (UTL_I18N.string_to_raw (l_oauth_base_string, ‘AL32UTF8’), DBMS_CRYPTO.hmac_sh1, UTL_I18N.string_to_raw (l_oauth_key, ‘AL32UT) DBMS_OUTPUT.put_line (‘Sig combinate:’ || l_oauth_key); l_base64_sig_mac: = UTL_RAW.cast_to_varchar2 (UTL_ENCODE.base64_encode (l_sig_mac)); DBMS_OUTPUT.put_line (‘Semnatura MAC (bazata pe 64):’ || l_base64_sig_mac); l_update_send: = l_oauth_request_token_url || ‘? status =’ || l_content; http_req: = UTL_HTTP.begin_request (l_update_send, l_http_method, UTL_HTTP.http_version_1_1); DBMS_OUTPUT.put_line (‘UPDATE URL’ || l_update_send); UTL_HTTP.set_response_error_check (TRUE); UTL_HTTP.set_detailed_excp_support (TRUE); l_oauth_header: = ‘OAuth oauth_nonce = „‘ || l_oauth_nonce || ‘”,’ || ‘oauth_signature_method = „‘ || l_oauth_signature_method || ‘”,’ || ‘oauth_timestamp = „‘ || l_oauth_timestamp || ‘”,’ || ‘oauth_consumer_key = „‘ || l_oauth_consumer_key || ‘”,’ || ‘oauth_token = „‘ || l_oauth_token || ‘”,’ || ‘oauth_signature = „‘ || urlencode (l_base64_sig_mac) || ​​'”,’ || ‘Oauth_version = „‘ || l_oauth_version || ‘”‘; utl_http.set_header (r => http_req, NAME => ‘Autorizare’, VALUE => l_oauth_header); DBMS_OUTPUT.put_line (‘HEADER:’ || l_oauth_header); utl_http.write_text (r => http_req > l_content); http_resp: = utl_http.get_response (r => http_req); DBMS_OUTPUT.put_line (‘GETTING RESPONSE HEADERS!’); FOR i IN 1..utl_http.get_header_count (http_resp) LOOP utl_http.get () resp_name, resp_value); dbms_output.put_line (resp_name || ‘:’ || resp_value); END LOOP; DBMS_OUTPUT.put_line (‘Obtinere continut:’); BEGIN LOOP utl_http.read_line (http_resp, resp_value, TRUE); dbms_output.put_ (resp_value); END LOOP; EXCEPTION WHEN utl_http.end_of_body THEN DBMS_OUTPUT.put_line (‘Nu mai exista continut.’); END; utl_http.end_response (r => http_resp); EXCEPTION cand altii apoi DBMS_OUTPUT.put_line (‘EROARE HTTP:’ || utl_http.get_detailed_sqlerrm); SFARSIT;

Nota antetul autorizatiei: „Autorizarea:” a disparut. Cand este prezent, nu functioneaza cumva.

Inveliti

Probele de cod de mai sus ar trebui sa va ajute sa utilizati formularul Twitter intr-o baza de date Oracle. L-am testat cu Oracle 10g XE.

Daca primiti un HTTP 401, va rugam sa verificati oauth_nonce: acela trebuie sa fie unic si nu prea mic (da, foarte vag …).