File Coverage

blib/lib/OAuth/Consumer.pm
Criterion Covered Total %
statement 30 162 18.5
branch 0 54 0.0
condition 0 15 0.0
subroutine 10 22 45.4
pod 3 7 42.8
total 43 260 16.5


line stmt bran cond sub pod time code
1             package OAuth::Consumer;
2             our $VERSION = '0.03';
3 4     4   249769 use strict;
  4         9  
  4         140  
4 4     4   21 use warnings;
  4         9  
  4         122  
5 4     4   22 use feature 'switch';
  4         10  
  4         307  
6 4     4   21 use Carp;
  4         6  
  4         240  
7 4     4   4570 use IO::Socket::INET;
  4         90715  
  4         36  
8 4     4   6489 use URI::Escape;
  4         7187  
  4         317  
9 4     4   4049 use HTTP::Response;
  4         134760  
  4         166  
10 4     4   4610 use Encode;
  4         72095  
  4         452  
11 4     4   4246 use HTML::Entities;
  4         32949  
  4         408  
12 4     4   109 use parent 'LWP::Authen::OAuth';
  4         8  
  4         37  
13              
14             =encoding utf-8
15              
16             =head1 NAME
17              
18             OAuth::Consumer - LWP based user agent with OAuth for consumer application
19              
20             =head1 SYNOPSIS
21              
22             OAuth is a protocol to allow a user to authorize an application to access on its
23             behalf ressources on a server without giving its password to the application. To
24             achieve this aim OAuth have a fairly complicated 3-steps authentication mechanism
25             which require to user to go to a website to authenticate itself. The authentication
26             response is then sent-back by the user itself through a callback mechanism.
27              
28             OAuth::Consumer hide away to complexity of this process, including the set-up of
29             a callback webserver which can be called by the user browser when its
30             authentication is performed.
31              
32             This library is oriented toward desktop application, it could possibly be used
33             in a web application but I have not tried it (and the LWP setup may not be the
34             most appropiate in this case).
35              
36             Authenticating your application with OAuth to access some user's ressources is
37             a matter of requesting and authorising a I. This can be done with the
38             following steps:
39              
40             use OAuth::Consumer;
41            
42             my $ua = OAuth::Consumer->new(
43             oauth_consumer_key => 'key',
44             oauth_consumer_secret => 'secret'
45             oauth_request_token_url => 'http://provider/oauth/request_token',
46             oauth_authorize_url => 'http://provider/oauth/authorize',
47             oauth_access_token_url => 'http://provider/oauth/access_token'
48             );
49            
50             my $verifer_url = $ua->get_request_token();
51            
52             print "You should authentify yourself at this URL: $verifier_url\n";
53            
54             my ($token, $secret) = $ua->get_access_token()
55            
56             At this point, C<$ua> is an OAuth enabled LWP user-agent that you can use to
57             access OAuth protected ressources. You should save the C<$token> and C<$secret>
58             that you got and, in a later session, you may just do the following to gain
59             access to the protected ressources:
60              
61             my $ua = OAuth::Consumer->new(
62             oauth_consumer_key => 'key',
63             oauth_consumer_secret => 'secret'
64             oauth_token_=> $token,
65             oauth_token_secret => $secret
66             );
67              
68             =head1 DESCRIPTION
69              
70             As OAuth::Consumer is a high-level library, this documentation does not describe
71             precisely the OAuth protocol. You may find documentation on this protocol on
72             these websites:
73              
74             =over 4
75              
76             =item L
77              
78             =item L
79              
80             =item L
81              
82             =item L
83              
84             =back
85              
86              
87             =head1 CONSTRUCTOR
88              
89             my $ua = OAuth::Consumer->new(%args);
90              
91             The OAuth::Consumer constructor gives you an LWP::UserAgent object (well, strictly
92             speaking this is an LWP::Authen::OAuth object, but you should not use directly
93             the method of this module). This object is able to authenticate using the OAuth
94             1.0 or 1.0a protocol (but not OAuth 2.0).
95              
96             You can give to the constructor any LWP::UserAgent arguments. The OAuth::Consumer
97             constructor expects some additionnal arguments described here:
98              
99             =over 4
100              
101             =item * C and C
102              
103             These values are specific to your application. Depending on the service you are
104             trying to access, you may either choose them arbitrarily, you may be given them
105             by the service provider (e.g. on your application page after registration for
106             Twitter or Google), or they may be fixed to some specific values.
107              
108             If you specify nothing, the default value of C is used for both (some
109             OAuth provider are known to accept this -- e.g. the Tomboy sync service -- this
110             may not be the case of the service you are trying to access).
111              
112             =item * C and C
113              
114             The whole point of the OAuth protocol is for an application to get an access token
115             and an associated secret. The consumer key and secret are associated to an
116             application, but the token and its secret are associated to a specific user of
117             this application.
118              
119             If you already have those (e.g. some service provider, like Twitter, will give
120             it to your user on there)
121              
122             =item * C, C, and C
123              
124             These are the OAuth endpoints. If you already have an C and
125             C then you do not need these endpoints, otherwise they should
126             be provided to you by the service provider.
127              
128             Some service provider will provide already authorised tokens and as such will not
129             provide an C. In this case, you should give C<'null'> for
130             this parameter and use the C<'manual'> type for C (see
131             below).
132              
133             =item * C
134              
135             You may specify the oauth version to use. Currently only version C<'1.0'> and
136             C<'1.0a'> are supported by the library. The default is C<'1.0a'>, you may need to
137             revert to C<'1.0'> with some server.
138              
139             =item * C
140              
141             Only the C signature mode is supported for now (which happens to be
142             the default value of this option). So you should not use this argument.
143              
144             =item * C
145              
146             This parameter allows you to specify the where the user will be sent by the
147             service provider once he has authorised your application. If you do not specify
148             anything for this parameter, it default to C where C
149             is a randomly chosen port where the library will listen for the end of the
150             authorisation procedure.
151              
152             You should not overide this value unless you are familiar with the OAuth protocol
153             and you know what you are doing.
154              
155             Some service providers (such as Google), allow the special value C<'oob'> (out of
156             band) which will redirect the user to a web page which will show the verifier
157             value. This value may then be passed as parameter to the C
158             method. This C<'oob'> value is the default when the C is
159             C (see just below).
160              
161             =item * C
162              
163             This parameter allows to specify how the verifier code is received by your
164             application. Currently the library support three modes. The default is
165             C<'blocking'>. In this mode, a call to C will be blocking until
166             the user complete its authentication process at the url given as the result of
167             the C call. During this time, the library will have set up a
168             small web server which will wait to be triggered by the user browser at the end
169             of this authentication.
170              
171             If this setting is not working for you, you may use an C of
172             C<'manual'>. In this case, no web server is set up by the library and you must
173             supply the I code manually to the C method. This
174             verifier may be entered by your user (some service provider will show it to your
175             user) or you may read eat programatically (e.g. performing the authorisation
176             process with WWW::Mechanize directed at the URL which is given back by the
177             C method).
178              
179             The C mode is the default if you supply an C argument to
180             the constructor.
181              
182             Finally there is the C mode. This mode is similar in functionnalities to
183             the C mode except that the small web server (which get the result of
184             the authentication) is run in a separate thread. This enable you more flexibilities
185             as you can complete the authentication process (be it by your user or with a
186             programatic method) before calling the C. Obviously, you will
187             need a Perl with threads enabled to use this mode.
188              
189             You should also note that in C mode the library itself is not thread-safe!
190             It plays with the C handler and as such it should be called from the main
191             thread of the program. Also, there may not be multiple concurently running
192             OAuth::Consumer object (that is in-between the C and
193             C call) if you are in C mode.
194              
195             =item * C and C
196              
197             You can use these two options to customise the message that the user get after its
198             authentication in the browser. You may either pass a string of text which will
199             be embedded in a small web page, or you may pass a complete web page (which must
200             then start with the C<<''>> tag to be recognised) which will be used as-is.
201             In the later case the argument must be UTF-8 encoded (not in Perl internal string
202             representation) with all HTML entities properly escaped (but no checks at all
203             will be performed on the argument beyond the test for the first tag).
204              
205             =item * C
206              
207             This parameter set the timeout value in the C method call.
208             That is, the time the user have to performs its authentication on the service
209             provider website. This parameter is ignored when C is
210             C.
211              
212             The default value is C<180> (3 minutes). You may set it to C to
213             completely remove any timeout.
214              
215             =back
216              
217              
218             =head1 METHODS
219              
220             The methods described here allow you to get an authorised access token and its
221             associated secret. If you already have those (maybe from previous call to these
222             methods) then you do not need them.
223              
224             An OAuth::Consumer object is also an LWP::UserAgent object and as such you can
225             use any method of the LWP::UserAgent class with an OAuth::Consumer object. If
226             your object is properly identified you may use it directly (e.g. with its C
227             or C method) to access OAuth protected ressources (that is, directly after
228             it is constructed if you provided valid C and C
229             to the constructor, or after a call to C/C
230             if you need a new token).
231              
232             =head2 get_request_token
233              
234             my $verifer_url = $ua->get_request_token(%args)
235              
236             This call initiates a new authorisation procedure. It does not expect any
237             arguments but you can provide any additionnal OAuth argument required by your
238             service provider. Example of such argument are C, C,
239             or C. You should look at the documentation of your service provider to
240             know which arguments it expects. These arguments will be added as POST arguments
241             in the OAuth query. If you need to pass them as GET arguments (in the url of the
242             query), then you should modify yourself the C that you
243             give to the constructor of the class.
244              
245             On success, this method returns a string containing an URL to which the
246             application user should be directed to authorise your application to access to
247             the service provider on behalf of this user. At the end of its authorisation the
248             user's browser will be automatically redirected to a small web server set up by
249             the library. This web server will automatically read the C code that
250             is given by the service provider.
251              
252             You may also use this C to programatically authorise your request
253             (e.g. with WWW::Mechanize).
254              
255             Finally, if your service provider does not need you to authenticate your token
256             then the return value may be ignored and you may directly call the
257             C method. In that case you must set the C
258             to C to prevent the application from blocking.
259              
260             The method will C in case of error.
261              
262             =head2 get_access_token
263              
264             my ($token, $secret) = $ua->get_access_token(%args)
265              
266             Once you have redirected your user to the verifier url, you can call this method.
267             It will block until the user finishes authenticating itself on the service
268             provider's website. If this process takes more time than the value of the
269             C parameter (in the constructor) then the method will
270             croak with the following message: C<'Timeout error while waiting for a callback connection'>.
271             You can trap this error (with C) and, optionnaly, restart the call to
272             C (which will wait for the same duration) if the C
273             is C (you may not call this function more than once per call to
274             C in C mode).
275              
276             If the C parameter is C<'blocking'> you must call this
277             function as soon as you have instructed your user to authenticate at the
278             I URL.
279              
280             If the C parameter is C<'manual'> then this function will
281             not block. But then you I specify an C named argument to
282             this function with its value being the value of the verifier that you got (your
283             user may have entered it in your application if your using out-of-bound
284             verification).
285              
286             If your service provider does not require you to verify the request token (and
287             as such did not give you an C). You must use C<'manual'>
288             mode with a dummy C in the constructor and you should pass
289             an empty value to the C argument of this method.
290              
291             All other arguments in the C<%args> hash will be passed with the I
292             query. To the author knowledge, no service providers require any arguments with
293             this query (as opposed to the I query).
294              
295             Finally, this function plays with the C function and associated handler.
296             So you should not rely on alarm handler set accross this function call.
297              
298             =cut
299              
300              
301             my @internal_opts = qw(
302             oauth_request_token_url oauth_authorize_url oauth_access_token_url
303             oauth_version oauth_callback oauth_verifier_type oauth_verifier_valid_msg
304             oauth_verifier_invalid_msg oauth_verifier_timeout);
305              
306             my $max_content_len_for_error = 60;
307              
308             sub new {
309 0     0 1   my ($class, %args) = @_;
310              
311 0           my %opts;
312 0           for my $o (@internal_opts)
313             {
314 0           $opts{$o} = delete $args{$o};
315             }
316            
317 0   0       $args{oauth_consumer_key} ||= 'anyone';
318 0   0       $args{oauth_consumer_secret} ||= 'anyone';
319              
320 0   0       $opts{oauth_version} ||= '1.0a';
321 0 0 0       $opts{oauth_verifier_type} ||= $opts{oauth_callback} ? 'manual' : 'blocking';
322 0   0       $opts{oauth_verifier_valid_msg} ||= 'Authentication accepted you can go back to the application';
323 0   0       $opts{oauth_verifier_invalid_msg} ||= 'There have been a problem with your authentication';
324 0   0       $opts{oauth_verifier_timeout} //= 180; # /
325            
326 0           given($opts{oauth_verifier_type}) {
327 0           when(/^(manual|blocking)$/) { }
328 0           when('thread') {
329 0 0         if (not eval 'use threads; 1') {
    0          
330 0           croak "You need a thread enabled Perl to a use oauth_verifier_type of 'thread'";
331             } elsif (not eval 'use Thread::Queue; 1') {
332 0           croak "You need 'Thread::Queue' to use a oauth_verifier_type of 'thread'";
333             }
334             }
335 0           default {
336 0           croak "Unknown value for the oauth_verifier_type parameter: ".$opts{oauth_verifier_type};
337             }
338             }
339              
340 0           my $self = $class->SUPER::new(%args);
341              
342 0           for(keys %opts)
343             {
344 0           $self->{$_} = $opts{$_};
345             }
346              
347 0           return $self;
348             }
349              
350              
351             sub m__start_server {
352 0     0 0   my ($self) = @_;
353              
354 0           my $sock = IO::Socket::INET->new(
355             Listen => 1,
356             LocalAddr => 'localhost',
357             LocalPort => 0,
358             Proto => 'tcp',
359             Timeout => $self->{oauth_verifier_timeout}
360             );
361              
362 0 0         return unless $sock;
363              
364 0           $self->{oauth_consumer_server_sock} = $sock;
365 0           $self->{oauth_consumer_server_port} = $sock->sockport();
366 0 0         carp "ignored oauth_callback parameter" if $self->{oauth_callback};
367 0           $self->{oauth_callback} = "http://localhost:".$sock->sockport().'/oauth_callback';
368              
369 0           return $self->{oauth_callback};
370             }
371              
372             sub __forge_response {
373 0     0     my ($ok, $txt) = @_;
374            
375 0 0         my $code = $ok ? 200 : 500;
376 0 0         my $msg = $ok ? 'OK' : 'Server Error';
377 0           my $content;
378 0 0         if ($txt =~ m/^\s*/) {
379 0           $content = $txt;
380             } else {
381 0           $content = encode('UTF-8', '

'.encode_entities($txt).'

');
382             }
383            
384 0           my $m = HTTP::Response->new($code, $msg, [
385             'Content-Type' => 'text/html;charset=UTF-8',
386             'Content-Length' => length($content)
387             ], $content);
388 0           $m->protocol("HTTP/1.0");
389              
390 0           return $m->as_string();
391             }
392              
393             sub m__get_verifier {
394 0     0 0   my ($self) = @_;
395              
396 0           my $sock = $self->{oauth_consumer_server_sock}->accept();
397 0 0         return 'OAUTH::CONSUMER::ERR:Timeout error while waiting for a callback connection' unless $sock;
398 0           $self->{oauth_consumer_server_sock}->close();
399              
400 0           my $get_line;
401 0           eval {
402 0     0     local $SIG{ALRM} = sub { die "Timeout error while reading the callback data\n" };
  0            
403 0           alarm 5;
404 0           $get_line = $sock->getline();
405 0           alarm 0;
406             };
407 0 0         return "OAUTH::CONSUMER::ERR:$@" if $@;
408              
409 0 0         if ($get_line =~ m{^GET\s+/oauth_callback.*oauth_verifier=([-0-9a-z_]+)}i) {
410 0           $self->{oauth_verifier} = $1;
411 0           $sock->print(__forge_response(1, $self->{oauth_verifier_valid_msg}));
412 0           $sock->close();
413 0           return $self->{oauth_verifier};
414             } else {
415 0           $sock->print(__forge_response(0, $self->{oauth_verifier_invalid_msg}));
416 0           $sock->close();
417 0           return "OAUTH::CONSUMER::ERR:no match in GET line '$get_line'";
418             }
419             }
420              
421             sub m__get_thread_verifier {
422 0     0 0   my ($self) = @_;
423              
424 0           $self->{thread}->join();
425 0           delete $self->{thread};
426 0           $SIG{ALRM} = $self->{previous_alrm_handler};
427             # On n'utilise pas la valeur de retour du thread pour faire quelquechose de
428             # plus facilement extensible.
429 0           return $self->{thread_queue}->dequeue();
430             }
431              
432             sub DESTROY {
433 0     0     my ($self) = @_;
434              
435 0 0         if ($self->{thread}) {
436 0 0         if ($self->{thread}->is_joinable()) {
437 0           $self->{thread}->join();
438             } else {
439 0           $self->{thread}->detach();
440             }
441             }
442             }
443              
444             sub m__start_thread_server {
445 0     0 0   my ($self) = @_;
446              
447 0           $self->{thread_queue} = Thread::Queue->new();
448              
449             $self->{thread} = threads->create(sub {
450 0     0     $self->{thread_queue}->enqueue($self->m__start_server());
451 0           $self->{thread_queue}->enqueue($self->m__get_verifier());
452 0           });
453              
454 0           $self->{previous_alrm_handler} = $SIG{ALRM};
455             $SIG{ALRM} = sub {
456 0     0     $self->{thread}->is_running();
457 0           $self->{thread}->kill('ALRM');
458 0           };
459              
460 0           return $self->{thread_queue}->dequeue();
461             }
462              
463             sub get_request_token {
464 0     0 1   my ($self, %args) = @_;
465            
466 0           my $ver_type = $self->{oauth_verifier_type};
467 0 0         croak "oauth_request_token_url must be set" unless $self->{oauth_request_token_url};
468 0 0         croak "oauth_authorize_url must be set" unless $self->{oauth_authorize_url};
469 0 0         croak "Invalid oauth_verifier_type: $ver_type" unless $ver_type =~ m/^(manual|blocking|thread)$/;
470              
471 0           given($ver_type) {
472 0           when('blocking') {
473 0           $self->{oauth_callback} = $self->m__start_server();
474 0 0         croak "Cannot open the verifier callback: $!" unless $self->{oauth_callback};
475             }
476 0           when('thread') {
477 0           $self->{oauth_callback} = $self->m__start_thread_server();
478 0 0         croak "Cannot open the verifier callback: $!" unless $self->{oauth_callback};
479             }
480 0           when('manual') {
481 0 0         if (not $self->{oauth_callback}) {
482             # we must supply a callback
483             # carp "You should provide a value for the 'oauth_callback' parameter";
484 0           $self->{oauth_callback} = 'oob';
485             }
486             }
487 0           default {
488 0           croak "Unknown value for the oauth_verifier_type parameter: $ver_type";
489             }
490             }
491 0           my $cback = uri_escape($self->{oauth_callback});
492              
493             # request a 'request' token
494 0           my $r = $self->post($self->{oauth_request_token_url}, Authorization => "OAuth oauth_callback=\"$cback\"", %args);
495 0 0         if ($r->is_error) {
496 0 0         my $str = length $r->content > $max_content_len_for_error ?
497             substr($r->content, 0, $max_content_len_for_error - 3).'...'
498             : $r->content;
499 0           croak "error during the GetRequestToken call: ".$r->message." ($str)";
500             }
501              
502 0           $self->oauth_update_from_response($r);
503 0           my $token = $self->oauth_token();
504 0           my $auth_url = $self->{oauth_authorize_url}."?oauth_token=$token";
505 0 0         if ($self->{oauth_version} eq '1.0') {
506 0           $auth_url .= '&oauth_callback='.$cback;
507             }
508              
509 0           return $auth_url;
510             }
511              
512              
513              
514             sub get_access_token {
515 0     0 1   my ($self, %args) = @_;
516              
517 0 0         croak "oauth_access_token_url must be set" unless $self->{oauth_access_token_url};
518              
519 0           given($self->{oauth_verifier_type}) {
520 0           when('blocking') {
521 0           $self->{oauth_verifier} = $self->m__get_verifier();
522             }
523 0           when('thread') {
524 0           $self->{oauth_verifier} = $self->m__get_thread_verifier();
525             }
526 0           when('manual') {
527 0 0         croak 'You must supply a oauth_verifier' unless exists $args{oauth_verifier};
528 0           $self->{oauth_verifier} = delete $args{oauth_verifier};
529             }
530 0           default {
531 0           croak "Unknown value for the oauth_verifier_type parameter: ".$self->{oauth_verifier_type};
532             }
533             }
534 0 0         if ($self->{oauth_verifier} =~ m/^OAUTH::CONSUMER::ERR:(.*?)$/m) {
535 0           croak $1;
536             }
537              
538 0           my $verif_header = 'OAuth oauth_verifier="'.uri_escape($self->{oauth_verifier}).'"';
539 0           my $r = $self->post($self->{oauth_access_token_url}, Authorization => $verif_header, %args);
540 0 0         if ($r->is_error) {
541 0 0         my $str = length $r->content > $max_content_len_for_error ?
542             substr($r->content, 0, $max_content_len_for_error - 3).'...'
543             : $r->content;
544 0           croak "error during the GetAccessToken call: ".$r->message." ($str)";
545             }
546 0           $self->oauth_update_from_response($r);
547            
548 0           my $token = $self->oauth_token();
549 0           my $secret = $self->oauth_token_secret();
550              
551 0           return ($token, $secret);
552             }
553              
554              
555              
556              
557             1;
558              
559              
560              
561              
562             =head1 EXAMPLES
563              
564             =head2 Getting an access token and secret
565              
566             Here are the steps to follow to request an access token from a ressource
567             provider. To achieve this, you need the 3 endpoints URL that should be described
568             in the documentation of the API of the provider. You also need a consumer key and
569             secret. Depending on the provider and the service, these value may be fixed to
570             a specific value or you may need to register your application at the provider
571             website to get them.
572              
573             Some providers require extra arguments for the C call. These
574             arguments are not mendatory in the OAuth specification but you should check the
575             API documentation of your service provider to know what it expects.
576              
577             my $ua = OAuth::Consumer->new(
578             oauth_consumer_key => 'my-consumer-key',
579             oauth_consumer_secret => 'my-consumer-secret',
580             oauth_request_token_url => 'http://oauth-provider.example.com/request_token',
581             oauth_access_token_url => 'http://oauth-provider.example.com/access_token',
582             oauth_authorize_url => 'http://oauth-provider.example.com/authorize',
583             );
584            
585             my $verifier_url = $ua->get_request_token(
586             scope => 'http://oauth-provider.example.com/scope1',
587             xoauth_displayname => 'My Application Name'
588             );
589            
590             # Send your user to $verifier_url to authenticate or use a WWW::Mechanize
591             # robot to performs the authentication programatically. In this later case,
592             # you should use the "oauth_verifier_type => thread" argument in the call to
593             # new to ensure that the authentication can terminate before the call to
594             # get_access_token.
595            
596             my ($token, $secret) = $ua->get_access_token();
597            
598             $r = $ua->get('http://oauth-provider.example.com/protected_ressource');
599              
600             At the end of this procedure you should store the C<$token> and C<$secret> values
601             as they should remains valid (usually service providers do not expire those).
602             You can then use them directly in a future session.
603              
604             =head2 Getting an access token and secret with out-of-bound (OOB) verifier
605              
606             If your service provider will not redirect your user to OAuth::Consumer
607             validation page, or if it is not feasible to ask the user to use his browser on
608             the same machine as where the program is running, you may use out-of-bound
609             verification where the user will be shown the verification code and can then
610             enter it in your application.
611              
612             Not all service provider support the C callback scheme, so the example below
613             may not work correctly. An alternative is to redirect the user to a web page that
614             you control and that will show the user the verification code. Some practice about
615             this are discussed on this web page: L.
616              
617             my $ua = OAuth::Consumer->new(
618             oauth_consumer_key => 'my-consumer-key',
619             oauth_consumer_secret => 'my-consumer-secret',
620             oauth_verifier_type => 'manual',
621             oauth_request_token_url => 'http://oauth-provider.example.com/request_token',
622             oauth_access_token_url => 'http://oauth-provider.example.com/access_token',
623             oauth_authorize_url => 'http://oauth-provider.example.com/authorize',
624             );
625            
626             my $verifier_url = $ua->get_request_token();
627            
628             print "Please, authenticate yourself at: $verifier_url\n";
629             print "Type in the verification code that you got: ";
630             my $verifier = ;
631            
632             my ($token, $secret) = $ua->get_access_token(oauth_verifier => $verifier);
633            
634             $r = $ua->get('http://oauth-provider.example.com/protected_ressource');
635              
636             Be carefull that a verifier URL may not remain valid for a long time (usual
637             expiration time is around an hour).
638              
639             =head2 Using an access token and secret
640              
641             If you saved your user specific access token and secret from a previous session
642             or if your service provider does not allow for the authentication procedure and,
643             instead, gives directly the token and its secret to your user on some web page
644             (e.g. this is what Twitter does), then you can directly use these value in the
645             constructor of the OAuth::Consumer object and completely skip the authentication
646             procedure.
647              
648             my $ua = OAuth::Consumer->new(
649             oauth_consumer_key => 'my-consumer-key',
650             oauth_consumer_secret => 'my-consumer-secret',
651             oauth_token => $token,
652             oauth_token_secret => $secret
653             );
654            
655             $r = $ua->get('http://oauth-provider.example.com/protected_ressource');
656              
657             However, you should check your response code in case the token has been revoked
658             or has expired (in which cases you will probably get a status code of C<401> or
659             C<403>, but some servers return a C<500> status code).
660              
661             =head2 Two-legged request (tokenless or consumer mode)
662              
663             Some service provider only require a your consumer key to authorise the access
664             to some protected ressource. This is called two-legged request (as opposed to
665             the normal three-legged mode) or tokenless mode.
666              
667             In this case, once you got your consumer key and secret (probably from your
668             application page on the service provider website) you can just use those to
669             access protected ressource.
670              
671             my $ua = OAuth::Consumer->new(
672             oauth_consumer_key => 'my-consumer-key',
673             oauth_consumer_secret => 'my-consumer-secret',
674             );
675            
676             $r = $ua->get('http://oauth-provider.example.com/two-legged_ressource');
677              
678             =head1 CAVEATS
679              
680             =over 4
681              
682             =item * Currently only the OAuth 1.0 and 1.0a are supported. The OAuth 2.0 protocol
683             is quiet different from the 1.0 version (and varies greatly from one service
684             provider to an other) so there is no plan currently to upgrade thise library to
685             it.
686              
687             =item * Only the C signature mode is supported in the OAuth message. This
688             is partly due to the fact that this is the only mode supported by the LWP::Authen::OAuth
689             library from which OAuth::Consumer is inheriting and also to the fact that this
690             mode is supported by all major OAuth enabled service provider. Let me know if you
691             need another signature mode.
692              
693             =back
694              
695             =head1 BUGS
696              
697             Please report any bugs or feature requests to C, or
698             through the web interface at L.
699              
700             However note that the tests for this distribution all depend on external service
701             which may be unavailable or broken at some point. I have removed from the
702             distribution the test depending on unreliable provider but some errors may still
703             happen.
704              
705             =head1 SEE ALSO
706              
707             LWP::Authen::OAuth, LWP::UserAgent, OAuth::Simple, Net::OAuth, OAuth::Lite,
708             Net::OAuth::Simple, OAuth::Lite::Consumer
709              
710             =head1 AUTHOR
711              
712             Mathias Kende (mathias@cpan.org)
713              
714             =head1 VERSION
715              
716             Version 0.03 (March 2013)
717              
718             =head1 COPYRIGHT & LICENSE
719              
720             Copyright 2013 © Mathias Kende. All rights reserved.
721              
722             This program is free software; you can redistribute it and/or
723             modify it under the same terms as Perl itself.
724              
725             =cut
726              
727              
728