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