tfe Homepage

24/12/2010

OAuth Perl CGI et Twitter

Apres la courte explication sur ce qu'etait OAuth, voila un autre billet sur son utilisation avec Perl (en CGI).

Resume des etapes e  effectuer

  1. Obtenir le "request token" de twitter
  2. Rediriger l'utilisateur vers la page d'autorisation de twitter
  3. Obtenir l' "access token" de twitter
  4. Utiliser l'access token pour modifier son statut twitter par exemple

Pour l'ensemble de ces etapes, nous utiliserons le module Net::OAuth du CPAN.

Note importante: vous remarquerez que j'utilise un hash %tokens dans le code qui me permets de memoriser l'association token -> token_secret et l'utiliser plus tard lors de la reception du access token. Cela n'est permis que si vous utilisez FastCGI. En mode CGI classique, vous devrez enregistrer cette association dans une base de donnee.

Preliminaires

Pour utiliser l'identification OAuth, votre page doit etre connue des services de twitter. La premiere etape consiste e  cre©er une application, pour obtenir les differents elements essentiels a  l'identification:

  • Consumer key: Cle d'identification de votre page
  • Consumer secret: Cle de chiffrement

Request token

Le serveur va tout d'abord demander un request_token e  twitter pour rediriger celui-ci vers une page d'autorisation.

use Encode;
use Net::OAuth;
use LWP::UserAgent;
use URI::Escape;
use HTTP::Request::Common qw(POST);
$Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
    

my $url_request = "https://api.twitter.com/oauth/request_token";
my $url_authorize = "http://api.twitter.com/oauth/authorize";
my $url_access = "https://api.twitter.com/oauth/access_token";
my $url_update = "https://api.twitter.com/1/statuses/update.xml";

my %tokens = (); 
my $consumer_key="votre cle";
my $consumer_secret="votre cle de chiffrement";
my $nonce="dwadwadwa"; # carate¨res ale©atoires

my $callback="http://monhost/cgi-bin/monscript.pl";
my $request = Net::OAuth->request("request token")->new(
        consumer_key => $consumer_key,
        consumer_secret => $consumer_secret,
        request_url => $url_request,
        request_method => 'POST',
        signature_method => 'HMAC-SHA1',
        timestamp => time,
        nonce => $nonce,
        callback => $callback
        );  

$request->sign;


my $ua = LWP::UserAgent->new;
my $res = $ua->request(HTTP::Request::Common::POST $request->to_url); # Post message to the Service Provider

if ($res->is_success) {
    my $response = Net::OAuth->response('request token')->from_post_body($res->content);
    print "Status: 200 OK
Location: $url_authorize?oauth_token=".$response->token."

";
    $tokens{$response->token} = $response->token_secret;
}
else {
    print "ERROR";
}

Access token

Cette page est visitee automatiquement par l'utilisateur une fois acceptee l'autorisation. On reçoit deux parametres via GET: oauth_token et oauth_verifier.

Nous devons verifier ces valeurs aupres de twitter qui nous donnera en resultat le code definitif d'acces: access token y token secret.

my $token = "testestes" ; # recupere via GET HTTP de oauth_token
my $token_verifier = "testieum"; # Recupere via GET HTTP de oauth_verifier
# Cle de chiffrement que nous avions recu lors de la recuperation
# du request token
my $token_secret = "le token secret";

my $request = Net::OAuth->request("access token")->new(
        consumer_key => $consumer_key,
        consumer_secret => $consumer_secret,
        request_url => $url_access,
        request_method => 'POST',
        signature_method => 'HMAC-SHA1',
        verifier => $token_verifier,
        token => $token,
        token_secret => $token_secret,
        timestamp => time,
        nonce => $nonce,
        );  
$request->sign;

my $ua = LWP::UserAgent->new;
my $res = $ua->request(HTTP::Request::Common::POST $request->to_url); # Post message to the Service Provider

if ($res->is_success) {
    my $response = Net::OAuth->response('access token')->from_post_body($res->content);
    print "Status: 200 OK
Content-type: text/html

";
    print "Token final: $response->token
";
    print "Token secret final: $response->token_secret
";
}
else {
    print "Error recuperacion token!";
}

Envoie de message

Pour l'envoie du message, nous utilisons les token et token secret de l'utilisateur.

Les parametres du message envoye e  la page se font via le champs extra_params.

my $request = Net::OAuth->request("protected resource")->new(
            consumer_key => $consumer_key,
            consumer_secret => $consumer_secret,
            token => $token,
            token_secret => $token_secret,
            request_url => $url_update,
            request_method => 'POST',
            signature_method => 'HMAC-SHA1',
            timestamp => time,
            nonce => $nonce,
            extra_params => {status => Encode::decode_utf8($message)}
            );  
$request->sign;
my $ua = LWP::UserAgent->new;
my $res = $ua->request(HTTP::Request::Common::POST $request->to_url); # Post message to the Service Provider

if ($res->is_success) {
        my $response = Net::OAuth->response('request token')->from_post_body($res->content);
        print "Status: 200 OK
Location: $url_authorize?oauth_token=".$response->token."

";
        $tokens{$response->token} = $response->token_secret;
}
else { 
 # Gestion d'erreur...
}