- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / templates / articles / app_identity.html
1 <h1>User Authentication</h1>
2
3 <p>
4 Web authentication protocols utilize HTTP features,
5 but Chrome Apps run inside the app container;
6 they don’t load over HTTP and can’t perform redirects or set cookies.
7 </p>
8
9 <p>
10 Use the <a href="identity.html">Chrome Identity API</a>
11 to authenticate users:
12 the <code>getAuthToken</code> for users logged into their Google Account and
13 the <code>launchWebAuthFlow</code> for users logged into a non-Google account.
14 If your app uses its own server to authenticate users, you will need to use the latter.
15 </p>
16
17 <p class="note">
18 <b>API Samples: </b>
19 Want to play with the code?
20 Check out the
21 <a href="https://github.com/GoogleChrome/chrome-app-samples#authentication-and-user-identification">identity samples</a>.
22 </p>
23
24 <h2 id="how">How it works</h2>
25
26 <p>
27 Chrome Apps users have a Google account associated with their
28 profile. Apps can get OAuth2 tokens for these users using
29 the <code>getAuthToken</code> API.
30 </p>
31
32 <p>
33 Apps that want to perform authentication with non-Google identity
34 providers must call <code>launchWebAuthFlow</code>.  This method uses a
35 browser pop-up to show the provider pages and captures redirects to
36 the specific URL patterns.  The redirect URLs are passed to the app
37 and the app extracts the token from the URL.
38 </p>
39
40 <h2 id="google">Google account authentication</h2>
41
42 <p>
43 Here are the five steps you need to complete:
44 </p>
45
46 <ol>
47   <li>Add permissions to your manifest and upload your app.</li>
48   <li>Copy key in the installed <code>manifest.json</code> to
49     your source manifest, so that your application ID will stay
50     constant during development.</li>
51   <li>Get an OAuth2 client ID for your Chrome App.</li>
52   <li>Update your manifest to include the client ID and scopes.</li>
53   <li>Get the authentication token.</li>
54 </ol>
55
56 <h3 id="add_permissions">Add permissions and upload app</h3>
57
58 <p>
59 You need to make sure the identity permission is in your manifest.
60 You can then upload your app to the apps and extensions management
61 page (see <a href="publish_app.html">Publish</a>).
62 </p>
63
64 <pre data-filename="manifest.json">
65 "permissions": [
66   "identity"
67 ]
68 </pre>
69
70 <h3 id="copy_key">Copy key to your manifest</h3>
71
72 <p>
73 When you register your application in the Google OAuth console, you'll
74 provide your application's ID, which will be checked during token
75 requests. Therefore it's important to have a consistent application ID
76 during development.
77 </p>
78
79 <p>
80 To keep your application ID constant, you need to copy the key in the
81 installed
82 <code>manifest.json</code> to your source manifest.
83 It's not the most graceful task, but here's how it goes:
84 </p>
85
86 <ol>
87   <li>Go to your <a href="http://www.chromium.org/user-experience/user-data-directory">user data
88   directory</a>. Example on MacOs:
89   <code>~/Library/Application\ Support/Google/Chrome/Default/Extensions</code></li>
90   <li>List the installed apps and extensions and match your app ID on the apps and extensions
91   management page to the same ID here.</li>
92   <li>Go to the installed app directory (this will be a version within the app ID).
93   Open the installed <code>manifest.json</code> (pico is a quick way to open the file).</li>
94   <li>Copy the "key" in the installed <code>manifest.json</code> and paste it into your app's
95   source manifest file.</li>
96 </ol>
97
98 <h3 id="client_id">Get your OAuth2 client ID</h3>
99
100 <p>
101 You need to register your app
102 in the Google APIs Console
103 to get the client ID:
104 </p>
105
106 <ol>
107   <li>Login to the <a href="https://code.google.com/apis/console/">Google APIs Console</a>
108   using the same Google account used to upload your app to the Chrome Web Store. </li>
109   <li>Create a new project by expanding the drop-down menu in the top-left
110   corner and selecting the <strong>Create...</strong> menu item. </li>
111   <li> Once created and named, go to the "Services" navigation menu item and
112   turn on any Google services your app needs. </li>
113   <li> Go to the "API Access" navigation menu item and click on the
114   <strong>Create an OAuth 2.0 client ID...</strong> blue button. </li>
115   <li> Enter the requested branding information,
116   select the <strong>Installed application</strong> type. </li>
117   <li> Select <strong>Chrome Application</strong> and enter your application ID
118   (same ID displayed in the apps and extensions management page). </li>
119 </ol>
120
121 <p class="warning">
122 <strong>Warning: </strong>
123 If the app ID here does not match your app ID,
124 an error will occur when your app calls <a href="#token">getAuthToken()</a>.
125 </p>
126
127 <h3 id="update_manifest">Update your manifest with OAuth2 client ID and scopes</h3>
128
129 <p>
130 You need to update your manifest to include
131 the client ID and scopes.
132 Here's the sample "oauth2" for the
133 <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/gdrive">gdrive sample</a>:
134 </p>
135
136 <pre data-filename="manifest.json">
137 "oauth2": {
138     "client_id": "665859454684.apps.googleusercontent.com",
139     "scopes": [
140       "https://www.googleapis.com/auth/drive"
141     ]
142   }
143 </pre>
144
145 <h3 id="token">Get access tokens</h3>
146
147 <p>
148 You are now ready to get the auth token by calling
149 $ref:identity.getAuthToken.
150 </p>
151
152 <pre>
153 chrome.identity.getAuthToken({ 'interactive': true }, function(token) {
154   // Use the token.
155 });
156 </pre>
157
158 <h4 id="getAuthToken-prompts">User interaction</h4>
159
160 <p>
161 When calling <code>getAuthToken</code>, you can pass a flag
162 (<code>'interactive': true</code> in the example above) indicating
163 whether you want the API to be called in interactive mode or silent
164 mode.  If you invoke the API in interactive mode, the user is shown
165 a sign in and/or approval UI when necessary, as shown in the
166 screenshot below:
167 </p>
168 <img src="{{static}}/images/identity-api-ui.png"
169      width="853"
170      height="514"
171      alt="screenshot showing UI when an app uses the Identity API
172      to authenticate a Google account">
173
174 <p>
175 If you invoke the API in silent mode, the API will only return a token
176 if it's possible to produce one without showing any UI.  This is
177 useful in cases when an app is doing the flow at app startup, for
178 example, or in general in cases where there is no user gesture
179 involved.
180 </p>
181
182 <p>
183 The best practice we suggest is to use silent mode when there is no
184 user gesture involved and use interactive mode if there is a user
185 gesture (for example, the user clicked the Sign In button in your
186 app). Note that we do not enforce any gesture requirement.
187 </p>
188
189 <h4 id="getAuthToken-caching">Caching</h4>
190
191 <p>
192 Chrome has an in-memory cache of access tokens, so you can call
193 <code>getAuthToken</code> any time you need to use a token. Token
194 expiration is handled automatically by the cache.
195 </p>
196
197 <p>
198 You can see the current state of the token cache
199 on <code>chrome://identity-internals</code>.
200 </p>
201
202 <p>
203 There are some cases, such as when the user changes their password,
204 when non-expired access tokens will stop working. API calls using the
205 token will start returning with an HTTP status code 401. If you detect
206 that this has happened, you can remove the invalid token from Chrome's
207 cache by calling $ref:identity.removeCachedAuthToken.
208 </p>
209
210 <p>
211 Example of <code>removeCachedAuthToken</code> usage:
212 </p>
213
214 <pre>
215 // callback = function (error, httpStatus, responseText);
216 function authenticatedXhr(method, url, callback) {
217   var retry = true;
218   function getTokenAndXhr() {
219     chrome.identity.getAuthToken({/* details */},
220                                  function (access_token) {
221       if (chrome.runtime.lastError) {
222         callback(chrome.runtime.lastError);
223         return;
224       }
225
226       var xhr = new XMLHttpRequest();
227       xhr.open(method, url);
228       xhr.setRequestHeader('Authorization',
229                            'Bearer ' + access_token);
230
231       xhr.onload = function () {
232         if (this.status === 401 && retry) {
233           // This status may indicate that the cached
234           // access token was invalid. Retry once with
235           // a fresh token.
236           retry = false;
237           chrome.identity.removeCachedAuthToken(
238               { 'token': access_token },
239               getTokenAndXhr);
240           return;
241         }
242
243         callback(null, this.status, this.responseText);
244       }
245     });
246   }
247 }
248 </pre>
249
250 <h2 id="non">Non-Google account authentication</h2>
251
252 <p>
253 Here are the three steps you need to complete:
254 </p>
255
256 <ol>
257   <li>Register with the provider.</li>
258   <li>Add permissions for provider resources that your app will access.</li>
259   <li>Get the authentication token.</li>
260 </ol>
261
262 <h3 id="register_provider">Register with the provider</h3>
263
264 <p>
265 You need to register an OAuth2 client ID with the provider
266 and configure the client ID as a website.
267 For the  redirect URI to be entered during registration,
268 use the URL of the form:
269 <code>https://&lt;extension-id&gt;.chromiumapp.org/&lt;anything-here&gt;</code>
270 </p>
271
272 <p>
273 For example, if you app ID
274 is <code>abcdefghijklmnopqrstuvwxyzabcdef</code> and you want
275 <code>provider_cb</code> to be the path, to distinguish it with
276 redirect URIs from other providers, you should use:
277 <code>https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb</code>
278 </p>
279
280 <h3 id="permissions_provider">Add permissions for provider</h3>
281
282 <p>
283 To make cross-origin XHRs to Google API endpoints,
284 you need to whitelist those patterns in the permissions:
285 </p>
286
287 <pre data-filename="manifest.json">
288 "permissions": [
289   ...
290   "https://docs.google.com/feeds/",
291   "https://docs.googleusercontent.com/",
292   "https://www.website-of-provider-with-user-photos.com/photos/"
293 ]
294 </pre>
295
296 <h3 id="token2">Get the token</h3>
297
298 <p>
299 To get the token:
300 </p>
301
302 <pre>
303 chrome.identity.launchWebAuthFlow(
304   {'url': '&lt;url-to-do-auth&gt;', 'interactive': true},
305   function(redirect_url) { /* Extract token from redirect_url */ });
306 </pre>
307
308 <p>
309 The &lt;url-to-do-auth&gt; is whatever the URL is to do auth to the provider from a website.
310 For example, let us say that you are performing OAuth2 flow with a provider
311 and have registered your app with client id 123456789012345 and
312 you want access to user’s photos on the provider’s website:
313 <code>https://www.website-of-provider-with-user-photos.com/dialog/oauth?client_id=123456789012345&amp;<br>redirect_uri=https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb&amp;response_type=token&amp;scope=user_photos</code>
314 </p>
315
316 <p>
317 The provider will perform authentication and if appropriate,
318 will show login and/or approval UI to the user.
319 It will then redirect to
320 <code>https://abcdefghijklmnopqrstuvwxyzabcdef.chromiumapp.org/provider_cb#authToken=&lt;auth-token></code>
321 </p>
322
323 <p>
324 Chrome will capture that and invoke the callback
325 of the app with the full redirect URL.
326 The app should extract the token out of the URL.
327 </p>
328
329 <h3 id="launchWebAuthFlow-interactive">Interactive versus silent mode</h3>
330
331 <p>
332 When calling <code>launchWebAuthFlow</code>,
333 you can pass a flag (<code>'interactive': true</code> in the example above)
334 indicating whether you want the API to be called
335 in interactive mode or not (aka silent mode).
336 If you invoke the API in interactive mode,
337 the user is shown UI, if necessary,
338 to get the token (signin UI and/or approval UI;
339 or for that matter any provider specific UI).
340 </p>
341
342 <p>
343 If you invoke the API in silent mode,
344 the API will only return a token if the provider is able
345 to provide a token without showing any UI.
346 This is useful in cases when an app is doing the flow at app startup, for example,
347 or in general in cases where there is no user gesture involved.
348 </p>
349
350 <p>
351 The best practice we suggest is to use silent mode
352 when there is no user gesture involved and use interactive mode
353 if there is a user gesture (for example, the user clicked the Sign In button in your app).
354 Note that we do not enforce gesture requirement.
355 </p>
356
357 <p class="backtotop"><a href="#top">Back to top</a></p>