[MANUAL] English:
[zend.git] / documentation / manual / en / module_specs / Zend_Oauth-GettingStarted.xml
blob649f032af9cb10d1cec7ca88a2e2d4ef05ef4da0
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- Reviewed: no -->
3 <sect2 id="zend.oauth.introduction.getting-started">
4     <title>Getting Started</title>
6     <para>
7         With the OAuth protocol explained, let's show a simple example of it with
8         source code. Our new Consumer will be handling Twitter Status submissions.
9         To do so, it will need to be registered with Twitter in order to receive
10         an OAuth Consumer Key and Consumer Secret. This are utilised to obtain
11         an Access Token before we use the Twitter API to post a status message.
12     </para>
14     <para>
15         Assuming we have obtained a key and secret, we can start the OAuth workflow
16         by setting up a <classname>Zend_Oauth_Consumer</classname> instance as
17         follows passing it a configuration (either an array or <classname>
18         Zend_Config</classname> object).
19     </para>
21     <programlisting language="php"><![CDATA[
22 $config = array(
23     'callbackUrl' => 'http://example.com/callback.php',
24     'siteUrl' => 'http://twitter.com/oauth',
25     'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
26     'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
28 $consumer = new Zend_Oauth_Consumer($config);
29 ]]></programlisting>
31     <para>
32         The callbackUrl is the URI we want Twitter to request from our server
33         when sending information. We'll look at this later. The siteUrl is the
34         base URI of Twitter's OAuth API endpoints. The full list of endpoints include
35         http://twitter.com/oauth/request_token, http://twitter.com/oauth/access_token,
36         and http://twitter.com/oauth/authorize. The base siteUrl utilises a convention
37         which maps to these three OAuth endpoints (as standard) for requesting a
38         request token, access token or authorization. If the actual endpoints of
39         any service differ from the standard set, these three URIs can be separately
40         set using the methods <methodname>setRequestTokenUrl()</methodname>,
41         <methodname>setAccessTokenUrl()</methodname>,
42         and <methodname>setAuthorizeUrl()</methodname> or the configuration fields requestTokenUrl,
43         accessTokenUrl and authorizeUrl.
44     </para>
46     <para>
47         The consumerKey and consumerSecret are retrieved from Twitter when your
48         application is registered for OAuth access. These also apply to any OAuth
49         enabled service, so each one will provide a key and secret for your
50         application.
51     </para>
53     <para>
54         All of these configuration options may be set using method calls simply
55         by converting from, e.g. callbackUrl to setCallbackUrl().
56     </para>
58     <para>
59         In addition, you should note several other configuration values not
60         explicitly used: requestMethod and requestScheme. By default, <classname>
61         Zend_Oauth_Consumer</classname> sends requests as POST (except for a
62         redirect which uses GET). The customised client (see later) also includes its
63         authorization by way of a header. Some services may, at their discretion,
64         require alternatives. You can reset the requestMethod (which defaults
65         to Zend_Oauth::POST) to Zend_Oauth::GET, for example, and reset the
66         requestScheme from its default of Zend_Oauth::REQUEST_SCHEME_HEADER to one
67         of Zend_Oauth::REQUEST_SCHEME_POSTBODY or
68         Zend_Oauth::REQUEST_SCHEME_QUERYSTRING. Typically the defaults should work
69         fine apart from some exceptional cases. Please refer to the service provider's
70         documentation for more details.
71     </para>
73     <para>
74         The second area of customisation is how <acronym>HMAC</acronym> operates
75         when calculating/comparing them for all requests. This is configured using
76         the signatureMethod configuration field or <methodname>setSignatureMethod()
77         </methodname>. By default this is HMAC-SHA1. You can set it also to a provider's
78         preferred method including RSA-SHA1. For RSA-SHA1, you should also configure
79         RSA private and public keys via the rsaPrivateKey and rsaPublicKey configuration
80         fields or the <methodname>setRsaPrivateKey()</methodname> and
81         <methodname>setRsaPublicKey()</methodname> methods.
82     </para>
84     <para>
85         The first part of the OAuth workflow is obtaining a request token. This
86         is accomplished using:
87     </para>
89     <programlisting language="php"><![CDATA[
90 $config = array(
91     'callbackUrl' => 'http://example.com/callback.php',
92     'siteUrl' => 'http://twitter.com/oauth',
93     'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
94     'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
96 $consumer = new Zend_Oauth_Consumer($config);
98 // fetch a request token
99 $token = $consumer->getRequestToken();
100 ]]></programlisting>
102     <para>
103         The new request token (an instance of <classname>Zend_Oauth_Token_Request
104         </classname>) is unauthorized. In order to exchange it for an authorized
105         token with which we can access the Twitter API, we need the user to authorize
106         it. We accomplish this by redirecting the user to Twitter's authorize endpoint
107         via:
108     </para>
110     <programlisting language="php"><![CDATA[
111 $config = array(
112     'callbackUrl' => 'http://example.com/callback.php',
113     'siteUrl' => 'http://twitter.com/oauth',
114     'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
115     'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
117 $consumer = new Zend_Oauth_Consumer($config);
119 // fetch a request token
120 $token = $consumer->getRequestToken();
122 // persist the token to storage
123 $_SESSION['TWITTER_REQUEST_TOKEN'] = serialize($token);
125 // redirect the user
126 $consumer->redirect();
127 ]]></programlisting>
129     <para>
130         The user will now be redirected to Twitter. They will be asked to authorize
131         the request token attached to the redirect URI's query string. Assuming they
132         agree, and complete the authorization, they will be again redirected, this
133         time to our Callback URL as previously set (note that the callback URL is
134         also registered with Twitter when we registered our application).
135     </para>
137     <para>
138         Before redirecting the user, we should persist the request token to storage.
139         For simplicity I'm just using the user's session, but you can easily use a
140         database for the same purpose, so long as you tie the request token to the
141         current user so it can be retrieved when they return to our application.
142     </para>
144     <para>
145         The redirect URI from Twitter will contain an authorized Access Token. We
146         can include code to parse out this access token as follows - this source
147         code would exist within the executed code of our callback URI. Once parsed
148         we can discard the previous request token, and instead persist the access
149         token for future use with the Twitter API. Again, we're simply persisting
150         to the user session, but in reality an access token can have a long lifetime
151         so it should really be stored to a database.
152     </para>
154     <programlisting language="php"><![CDATA[
155 $config = array(
156     'callbackUrl' => 'http://example.com/callback.php',
157     'siteUrl' => 'http://twitter.com/oauth',
158     'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
159     'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
161 $consumer = new Zend_Oauth_Consumer($config);
163 if (!empty($_GET) && isset($_SESSION['TWITTER_REQUEST_TOKEN'])) {
164     $token = $consumer->getAccessToken($_GET, unserialize($_SESSION['TWITTER_REQUEST_TOKEN']));
165     $_SESSION['TWITTER_ACCESS_TOKEN'] = serialize($token);
167     // Now that we have an Access Token, we can discard the Request Token
168     $_SESSION['TWITTER_REQUEST_TOKEN'] = null;
169 } else {
170     // Mistaken request? Some malfeasant trying something?
171     exit('Invalid callback request. Oops. Sorry.');
173 ]]></programlisting>
175     <para>
176         Success! We have an authorized access token - so it's time to actually
177         use the Twitter API. Since the access token must be included with every
178         single API request, Zend_Oauth_Consumer offers a ready-to-go HTTP client
179         (a subclass of <classname>Zend_Http_Client</classname>) to use either
180         by itself or by passing it as a custom HTTP Client to another library or
181         component. Here's an example of using it standalone. This can be done
182         from anywhere in your application, so long as you can access the OAuth
183         configuration and retrieve the final authorized access token.
184     </para>
186     <programlisting language="php"><![CDATA[
187 $config = array(
188     'callbackUrl' => 'http://example.com/callback.php',
189     'siteUrl' => 'http://twitter.com/oauth',
190     'consumerKey' => 'gg3DsFTW9OU9eWPnbuPzQ',
191     'consumerSecret' => 'tFB0fyWLSMf74lkEu9FTyoHXcazOWpbrAjTCCK48A'
194 $statusMessage = 'I\'m posting to Twitter using Zend_Oauth!';
196 $token = unserialize($_SESSION['TWITTER_ACCESS_TOKEN']);
197 $client = $token->getHttpClient($configuration);
198 $client->setUri('http://twitter.com/statuses/update.json');
199 $client->setMethod(Zend_Http_Client::POST);
200 $client->setParameterPost('status', $statusMessage);
201 $response = $client->request();
203 $data = Zend_Json::decode($response->getBody());
204 $result = $response->getBody();
205 if (isset($data->text)) {
206     $result = 'true';
208 echo $result;
209 ]]></programlisting>
211     <para>
212         As a note on the customised client, this can be passed to most
213         Zend Framework service or other classes using <classname>Zend_Http_Client
214         </classname> displacing the default client they would otherwise use.
215     </para>
216 </sect2>