1Net::OAuth(3) User Contributed Perl Documentation Net::OAuth(3)
2
3
4
6 Net::OAuth - OAuth protocol support
7
9 # Consumer sends Request Token Request
10
11 use Net::OAuth;
12 $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
13 use HTTP::Request::Common;
14 my $ua = LWP::UserAgent->new;
15
16 my $request = Net::OAuth->request("request token")->new(
17 consumer_key => 'dpf43f3p2l4k3l03',
18 consumer_secret => 'kd94hf93k423kf44',
19 request_url => 'https://photos.example.net/request_token',
20 request_method => 'POST',
21 signature_method => 'HMAC-SHA1',
22 timestamp => '1191242090',
23 nonce => 'hsu94j3884jdopsl',
24 callback => 'http://printer.example.com/request_token_ready',
25 extra_params => {
26 apple => 'banana',
27 kiwi => 'pear',
28 }
29 );
30
31 $request->sign;
32
33 my $res = $ua->request(POST $request->to_url); # Post message to the Service Provider
34
35 if ($res->is_success) {
36 my $response = Net::OAuth->response('request token')->from_post_body($res->content);
37 print "Got Request Token ", $response->token, "\n";
38 print "Got Request Token Secret ", $response->token_secret, "\n";
39 }
40 else {
41 die "Something went wrong";
42 }
43
44 # Etc..
45
46 # Service Provider receives Request Token Request
47
48 use Net::OAuth;
49 $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
50 use CGI;
51 my $q = new CGI;
52
53 my $request = Net::OAuth->request("request token")->from_hash($q->Vars,
54 request_url => 'https://photos.example.net/request_token',
55 request_method => $q->request_method,
56 consumer_secret => 'kd94hf93k423kf44',
57 );
58
59 if (!$request->verify) {
60 die "Signature verification failed";
61 }
62 else {
63 # Service Provider sends Request Token Response
64
65 my $response = Net::OAuth->response("request token")->new(
66 token => 'abcdef',
67 token_secret => '0123456',
68 callback_confirmed => 'true',
69 );
70
71 print $response->to_post_body;
72 }
73
74 # Etc..
75
77 OAuth is
78
79 "An open protocol to allow secure API authentication in a simple and
80 standard method from desktop and web applications."
81
82 In practical terms, OAuth is a mechanism for a Consumer to request
83 protected resources from a Service Provider on behalf of a user.
84
85 Please refer to the OAuth spec: <http://oauth.net/documentation/spec>
86
87 Net::OAuth provides:
88
89 · classes that encapsulate OAuth messages (requests and responses).
90
91 · message signing
92
93 · message serialization and parsing.
94
95 · 2-legged requests (aka. tokenless requests, aka. consumer
96 requests), see "CONSUMER REQUESTS"
97
98 Net::OAuth does not provide:
99
100 · Consumer or Service Provider encapsulation
101
102 · token/nonce/key storage/management
103
105 OAUTH MESSAGES
106 An OAuth message is a set of key-value pairs. The following message
107 types are supported:
108
109 Requests
110
111 · Request Token (Net::OAuth::RequestTokenRequest)
112
113 · Access Token (Net::OAuth::AccessTokenRequest)
114
115 · User Authentication (Net::OAuth::UserAuthRequest)
116
117 · Protected Resource (Net::OAuth::ProtectedResourceRequest)
118
119 · Consumer Request (Net::OAuth::ConsumerRequest) (2-legged / token-
120 less request)
121
122 Responses
123
124 · Request Token (Net::OAuth::RequestTokenResponse)
125
126 · Access Token (Net::OAuth:AccessTokenResponse)
127
128 · User Authentication (Net::OAuth::UserAuthResponse)
129
130 Each OAuth message type has one or more required parameters, zero or
131 more optional parameters, and most allow arbitrary parameters.
132
133 All OAuth requests must be signed by the Consumer. Responses from the
134 Service Provider, however, are not signed.
135
136 To create a message, the easiest way is to use the factory methods
137 (Net::OAuth->request, Net::OAuth->response, Net::OAuth->message). The
138 following method invocations are all equivalent:
139
140 $request = Net::OAuth->request('user authentication')->new(%params);
141 $request = Net::OAuth->request('user_auth')->new(%params);
142 $request = Net::OAuth->request('UserAuth')->new(%params);
143 $request = Net::OAuth->message('UserAuthRequest')->new(%params);
144
145 The more verbose way is to use the class directly:
146
147 use Net::OAuth::UserAuthRequest;
148 $request = Net::OAuth::UserAuthRequest->new(%params);
149
150 You can also create a message by deserializing it from a Authorization
151 header, URL, query hash, or POST body
152
153 $request = Net::OAuth->request('protected resource')->from_authorization_header($header, %api_params);
154 $request = Net::OAuth->request('protected resource')->from_url($url, %api_params);
155 $request = Net::OAuth->request('protected resource')->from_hash($q->Vars, %api_params); # CGI
156 $request = Net::OAuth->request('protected resource')->from_hash($c->request->params, %api_params); # Catalyst
157 $response = Net::OAuth->response('request token')->from_post_body($response_content, %api_params);
158
159 Note that the deserialization methods (as opposed to new()) expect
160 OAuth protocol parameters to be prefixed with 'oauth_', as you would
161 expect in a valid OAuth message.
162
163 Before sending a request, the Consumer must first sign it:
164
165 $request->sign;
166
167 When receiving a request, the Service Provider should first verify the
168 signature:
169
170 die "Signature verification failed" unless $request->verify;
171
172 When sending a message the last step is to serialize it and send it to
173 wherever it needs to go. The following serialization methods are
174 available:
175
176 $response->to_post_body # a application/x-www-form-urlencoded POST body
177
178 $request->to_url # the query string of a URL
179
180 $request->to_authorization_header # the value of an HTTP Authorization header
181
182 $request->to_hash # a hash that could be used for some other serialization
183
184 API PARAMETERS vs MESSAGE PARAMETERS
185 Net::OAuth defines 'message parameters' as parameters that are part of
186 the transmitted OAuth message. These include any protocol parameter
187 (prefixed with 'oauth_' in the message), and any additional message
188 parameters (the extra_params hash).
189
190 'API parameters' are parameters required to build a message object that
191 are not transmitted with the message, e.g. consumer_secret,
192 token_secret, request_url, request_method.
193
194 There are various methods to inspect a message class to see what
195 parameters are defined:
196
197 $request->required_message_params;
198 $request->optional_message_params;
199 $request->all_message_params;
200 $request->required_api_params;
201 $request->optional_api_params;
202 $request->all_api_params;
203 $request->all_params;
204
205 E.g.
206
207 use Net::OAuth;
208 use Data::Dumper;
209 print Dumper(Net::OAuth->request("protected resource")->required_message_params);
210
211 $VAR1 = [
212 'consumer_key',
213 'signature_method',
214 'timestamp',
215 'nonce',
216 'token'
217 ];
218
219 ACCESSING PARAMETERS
220 All parameters can be get/set using accessor methods. E.g.
221
222 my $consumer_key = $request->consumer_key;
223 $request->request_method('POST');
224
225 THE REQUEST_URL PARAMETER
226 Any query parameters in the request_url are removed and added to the
227 extra_params hash when generating the signature.
228
229 E.g. the following requests are pretty much equivalent:
230
231 my $request = Net::OAuth->request('Request Token')->new(
232 %params,
233 request_url => 'https://photos.example.net/request_token',
234 extra_params => {
235 foo => 'bar'
236 },
237 );
238
239 my $request = Net::OAuth->request('Request Token')->new(
240 %params,
241 request_url => 'https://photos.example.net/request_token?foo=bar',
242 );
243
244 Calling $request->request_url will still return whatever you set it to
245 originally. If you want to get the request_url with the query
246 parameters removed, you can do:
247
248 my $url = $request->normalized_request_url;
249
250 SIGNATURE METHODS
251 The following signature methods are supported:
252
253 · PLAINTEXT
254
255 · HMAC-SHA1
256
257 · RSA-SHA1
258
259 The signature method is determined by the value of the signature_method
260 parameter that is passed to the message constructor.
261
262 If an unknown signature method is specified, the signing/verification
263 will throw an exception.
264
265 PLAINTEXT SIGNATURES
266
267 This method is a trivial signature which adds no security. Not
268 recommended.
269
270 HMAC-SHA1 SIGNATURES
271
272 This method is available if you have Digest::HMAC_SHA1 installed. This
273 is by far the most commonly used method.
274
275 RSA-SHA1 SIGNATURES
276
277 To use RSA-SHA1 signatures, pass in a Crypt::OpenSSL::RSA object (or
278 any object that can do $o->sign($str) and/or $o->verify($str, $sig))
279
280 E.g.
281
282 Consumer:
283
284 use Crypt::OpenSSL::RSA;
285 use File::Slurp;
286 $keystring = read_file('private_key.pem');
287 $private_key = Crypt::OpenSSL::RSA->new_private_key($keystring);
288 $request = Net::OAuth->request('request token')->new(%params);
289 $request->sign($private_key);
290
291 Service Provider:
292
293 use Crypt::OpenSSL::RSA;
294 use File::Slurp;
295 $keystring = read_file('public_key.pem');
296 $public_key = Crypt::OpenSSL::RSA->new_public_key($keystring);
297 $request = Net::OAuth->request('request token')->new(%params);
298 if (!$request->verify($public_key)) {
299 die "Signature verification failed";
300 }
301
302 Note that you can pass the key in as a parameter called 'signature_key'
303 to the message constructor, rather than passing it to the sign/verify
304 method, if you like.
305
306 CONSUMER REQUESTS
307 To send a request without including a token, use a Consumer Request:
308
309 my $request = Net::OAuth->request('consumer')->new(
310 consumer_key => 'dpf43f3p2l4k3l03',
311 consumer_secret => 'kd94hf93k423kf44',
312 request_url => 'http://provider.example.net/profile',
313 request_method => 'GET',
314 signature_method => 'HMAC-SHA1',
315 timestamp => '1191242096',
316 nonce => 'kllo9940pd9333jh',
317 );
318
319 $request->sign;
320
321 See Net::OAuth::ConsumerRequest
322
323 I18N
324 Per the OAuth spec, when making the signature Net::OAuth first encodes
325 parameters to UTF-8. This means that any parameters you pass to
326 Net::OAuth, if they are outside of ASCII character set, should be run
327 through Encode::decode() (or an equivalent PerlIO layer) first to
328 decode them to Perl's internal character sructure.
329
330 There is a check in Net::OAuth's parameter encoding function that
331 guesses if the data you are passing in looks like it is already UTF-8
332 and warns that you should decode it first. This accidental double-
333 encoding of UTF-8 may be a source of headaches - if you find that the
334 signature check is failing when you send non-ASCII data, that is a
335 likely cause.
336
337 You can silence this warning by setting:
338
339 $Net::OAuth::SKIP_UTF8_DOUBLE_ENCODE_CHECK = 1;
340
341 Following is an example of decoding some UTF-8 form data before sending
342 it in an OAuth messaage (from the Twitter demo included in the
343 Net::OAuth package):
344
345 my $request = Net::OAuth->request("protected resource")->new(
346 $self->_default_request_params,
347 request_url => 'http://twitter.com/statuses/update.xml',
348 token => $self->session->param('token'),
349 token_secret => $self->session->param('token_secret'),
350 request_method => 'POST',
351 extra_params => {status => decode_utf8($self->query->param('status'))}
352 );
353
354 OAUTH 1.0A
355 Background:
356
357 http://mojodna.net/2009/05/20/an-idiots-guide-to-oauth-10a.html
358 <http://mojodna.net/2009/05/20/an-idiots-guide-to-oauth-10a.html>
359
360 http://oauth.googlecode.com/svn/spec/core/1.0a/drafts/3/oauth-core-1_0a.html
361 <http://oauth.googlecode.com/svn/spec/core/1.0a/drafts/3/oauth-
362 core-1_0a.html>
363
364 Net::OAuth defaults to OAuth 1.0 spec compliance, and supports OAuth
365 1.0 Rev A with an optional switch:
366
367 use Net::OAuth
368 $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
369
370 It is recommended that any new projects use this switch if possible,
371 and existing projects move to supporting this switch as soon as
372 possible. Probably the easiest way for existing projects to do this is
373 to turn on the switch and run your test suite. The Net::OAuth
374 constructor will throw an exception where the new protocol parameters
375 (callback, callback_confirmed, verifier) are missing.
376
377 Internally, the Net::OAuth::Message constructor checks
378 $Net::OAuth::PROTOCOL_VERSION and attempts to load the equivalent
379 subclass in the Net::OAuth::V1_0A:: namespace. So if you instantiate a
380 Net::OAuth::RequestTokenRequest object, you will end up with a
381 Net::OAuth::V1_0A::RequestTokenRequest (a subclass of
382 Net::OAuth::RequestTokenRequest) if the protocol version is set to
383 PROTOCOL_VERSION_1_0A. You can also select a 1.0a subclass on a per-
384 message basis by passing
385
386 protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A
387
388 in the API parameters hash.
389
390 If you are not sure whether the entity you are communicating with is
391 1.0A compliant, you can try instantiating a 1.0A message first and then
392 fall back to 1.0 if that fails:
393
394 use Net::OAuth
395 $Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
396 my $is_oauth_1_0 = 0;
397 my $response = eval{Net::OAuth->response('request token')->from_post_body($res->content)};
398 if ($@) {
399 if ($@ =~ /Missing required parameter 'callback_confirmed'/) {
400 # fall back to OAuth 1.0
401 $response = Net::OAuth->response('request token')->from_post_body(
402 $res->content,
403 protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0
404 );
405 $is_oauth_1_0 = 1; # from now on treat the server as OAuth 1.0 compliant
406 }
407 else {
408 die $@;
409 }
410 }
411
412 At some point in the future, Net::OAuth will default to
413 Net::OAuth::PROTOCOL_VERSION_1_0A.
414
416 There is a demo Consumer CGI in this package, also available online at
417 <http://oauth.kg23.com/>
418
420 <http://oauth.net>
421
422 Check out Net::OAuth::Simple - it has a simpler API that may be more to
423 your liking
424
425 Check out Net::Twitter::OAuth for a Twitter-specific OAuth API
426
427 Check out WWW::Netflix::API for a Netflix-specific OAuth API
428
430 Keith Grennan, "<kgrennan at cpan.org>"
431
433 Copyright 2009 Keith Grennan, all rights reserved.
434
435 This program is free software; you can redistribute it and/or modify it
436 under the same terms as Perl itself.
437
438
439
440perl v5.12.0 2010-05-04 Net::OAuth(3)