| OLD | NEW |
| 1 <h1 id="lab_7_user_identity">Lab 7 - User Identity</h1> | 1 <h1 id="lab_7_user_identity">Access User's Data</h1> |
| 2 | 2 |
| 3 <p>Most modern applications are attached to the web to synchronize data. When sy
nchronizing data, you need to identify who the user is. | 3 <p>Most modern applications are attached to the web to synchronize data. When sy
nchronizing data, you need to identify who the user is. |
| 4 Chrome apps come with an <a href="http://developer.chrome.com/trunk/apps/experim
ental.identity.html">identity API</a> that makes it easy to integrate either wit
h Google accounts or with any other service that supports OAuth.</p> | 4 Chrome packaged apps come with an <a href="http://developer.chrome.com/trunk/app
s/experimental.identity.html">identity API</a> that makes it easy to integrate e
ither with Google accounts or with any other service that supports OAuth.</p> |
| 5 | 5 |
| 6 <ol> | 6 <ol> |
| 7 <li> Built in - Google Authenticiation</li> | 7 <li> Built in - Google Authenticiation</li> |
| 8 <li> Third Party Authentication (Twitter, Foursquare, etc.)</li> | 8 <li> Third Party Authentication (Twitter, Foursquare, etc.)</li> |
| 9 </ol> | 9 </ol> |
| 10 | 10 |
| 11 <h2 id="you_should_also_read">You should also read</h2> | 11 <p class="warning"><b>Warning:</b> |
| 12 | 12 Apps with authentication require the experimental permission in the |
| 13 <p><a href="http://developer.chrome.com/trunk/apps/app_identity.html">Identify U
ser</a> in Chrome app docs</p> | 13 <code>manifest.json</code> and, until they came out of experimental state, |
| 14 | 14 they cannot be uploaded to the Chrome Web Store. |
| 15 <p class="note"><b>Note:</b> Apps with authentication require the experimental
permission in the <code>manifest.json</code> and, until they came out of experim
ental state, they cannot be uploaded to the Chrome Web Store. | |
| 16 If you prefer, you can choose to skip this lab.</p> | 15 If you prefer, you can choose to skip this lab.</p> |
| 17 | 16 |
| 18 <h2 id="authenticating_with_google">Authenticating with Google</h2> | 17 <h2 id="authenticating_with_google">Authenticating with Google</h2> |
| 19 | 18 |
| 20 <p>We are working on a very easy integration flow for apps that authenticate wit
h Google accounts. However, this flow is not yet available for general use. In t
he meantime, you may still use the third-party flow described below, even for Go
ogle services.</p> | 19 <p>We are working on a very easy integration flow for apps that authenticate wit
h Google accounts. However, this flow is not yet available for general use. In t
he meantime, you may still use the third-party flow described below, even for Go
ogle services.</p> |
| 21 | 20 |
| 22 <h2 id="integrating_with_a_third_party_service">Integrating with a third-party s
ervice</h2> | 21 <h2 id="integrating_with_a_third_party_service">Integrating with a third-party s
ervice</h2> |
| 23 | 22 |
| 24 <p>Chrome apps have a dedicated API for lauching the authentication flow to any
third-party OAuth2 service, called $ref:experimental.identity.launchWebAuthFlow. | 23 <p>Chrome packaged apps have a dedicated API for lauching the authentication flo
w to any third-party OAuth2 service, called $ref:experimental.identity.launchWeb
AuthFlow. |
| 25 To show how this flow works, we're going to update our sample to import <a h
ref="https://developers.google.com/google-apps/tasks/">Google Tasks</a> into the
Todo list.</p> | 24 To show how this flow works, we're going to update our sample to import <a h
ref="https://developers.google.com/google-apps/tasks/">Google Tasks</a> into the
Todo list.</p> |
| 26 | 25 |
| 27 <h3 id="register_with_the_provider">Register with the provider</h3> | 26 <h3 id="register_with_the_provider">Register with the provider</h3> |
| 28 | 27 |
| 29 <p>To use a third-party OAuth2 provider, you will first need to register your ap
plication with the provider. Each provider has a different way of registering ap
plications, but in general it will be in a section called Developer or API at th
e provider's website.</p> | 28 <p>To use a third-party OAuth2 provider, you will first need to register your ap
plication with the provider. Each provider has a different way of registering ap
plications, but in general it will be in a section called Developer or API at th
e provider's website.</p> |
| 30 | 29 |
| 31 <p>Here we are treating Google as a third-party service. Just follow Google'
s own registration procedure for apps requiring API access below:</p> | 30 <p>Here we are treating Google as a third-party service. Just follow Google'
s own registration procedure for apps requiring API access below:</p> |
| 32 | 31 |
| 33 <ol> | 32 <ol> |
| 34 <li>Create a new project in the <a href="https://code.google.com/apis/console">G
oogle API console</a>.</li> | 33 <li>Create a new project in the <a href="https://code.google.com/apis/console">G
oogle API console</a>.</li> |
| 35 <li>Activate the Tasks API on the Services secion.</li> | 34 <li>Activate the Tasks API on the Services secion.</li> |
| 36 <li>Create a new OAuth2.0 client ID on API Access section. Select Web applicatio
n and leave other fields unchanged.</li> | 35 <li>Create a new OAuth2.0 client ID on API Access section. Select Web applicatio
n and leave other fields unchanged.</li> |
| 37 <li>Click on Edit settings for the newly created client ID.</li> | 36 <li>Click on Edit settings for the newly created client ID.</li> |
| 38 <li>In Authorized Redirect URLs, add <code>https://<YOURAPP_ID>.chromiumap
p.org/</code>, | 37 <li>In Authorized Redirect URLs, add <code>https://<YOURAPP_ID>.chromiumap
p.org/</code>, |
| 39 replacing <YOURAPP_ID> with your app ID (this is the app's long alphan
umeric ID you can find in <code>chrome://extensions</code>).</li> | 38 replacing <YOURAPP_ID> with your app ID (this is the app's long alphan
umeric ID you can find in <code>chrome://extensions</code>).</li> |
| 40 </ol> | 39 </ol> |
| 41 | 40 |
| 42 <h3 id="add_permissions">Add permissions</h3> | 41 <h3 id="add_permissions">Add permissions</h3> |
| 43 | 42 |
| 44 <p>Update the <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/m
aster/lab7_useridentification/angularjs/manifest.json">manifest.json</a> to use
"experimental" features. Note that we've also requested permission
to make XHR requests to the Tasks service URL - for security reasons, you need
to request explicit permission in the manifest for every URL you will call via X
HR. | 43 <p>Update the |
| 44 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7_use
ridentification/angularjs/manifest.json">AngularJS manifest.json</a> or |
| 45 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7_use
ridentification/javascript/manifest.json">JavaScript manifest.json</a> |
| 46 to use "experimental" features. |
| 47 Note that we've also requested permission |
| 48 to make XHR requests to the Tasks service URL - for security reasons, |
| 49 you need to request explicit permission in the manifest for every URL you will c
all via XHR. |
| 50 </p> |
| 51 |
| 45 <pre> | 52 <pre> |
| 46 { | 53 { |
| 47 ... , | 54 ... , |
| 48 "permissions": ["storage", "experimental", &q
uot;https://www.googleapis.com/tasks/*"] | 55 "permissions": ["storage", "experimental", &q
uot;https://www.googleapis.com/tasks/*"] |
| 49 } | 56 } |
| 50 </pre></p> | 57 </pre> |
| 51 | 58 |
| 52 <h3 id="add_google_tasks_to_the_todo_list">Add Google tasks to the Todo list</h3
> | 59 <h3 id="add_google_tasks_to_the_todo_list">Add Google tasks to the Todo list</h3
> |
| 53 | 60 |
| 54 <p>Now we are ready to ask user's authorization, so we can connect to the Ta
sks service and import his tasks into our Todo list. First, we will need to requ
est an access token - which, at the first run will automatically pops up an auth
entication and authorization window to the user. | 61 <p>Now we are ready to ask user's authorization, so we can connect to the Ta
sks service and import his tasks into our Todo list. First, we will need to requ
est an access token - which, at the first run will automatically pops up an auth
entication and authorization window to the user. |
| 55 Once we have this token, we are able to call the Google Tasks API directly.</p> | 62 Once we have this token, we are able to call the Google Tasks API directly.</p> |
| 56 | 63 |
| 57 <ol> | 64 <ol> |
| 58 <li><p>Since this is time consuming and error prone, you can cheat and copy our
JavaScript that handles the authentication to the Google Tasks API from here: <a
href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7_useri
dentification/angularjs/gapi_tasks.js">gapi_tasks.js</a>. | 65 <li><p>Since this is time consuming and error prone, you can cheat and copy our
JavaScript that handles the authentication to the Google Tasks API from here: <a
href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7_useri
dentification/angularjs/gapi_tasks.js">Angular gapi_tasks.js</a> |
| 59 This script calls <code>launchWebFlow</code> and gets a valid access token for t
he specified client ID. It also has simple JavaScript methods that, after authen
ticated, goes to the Tasks API and gets the user's task lists and the corres
ponding tasks. </p> | 66 and <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7
_useridentification/javascript/gapi_tasks.js">JavaScript gapi_tasks.js</a> are t
he same. |
| 67 This script calls <code>launchWebFlow</code> and |
| 68 gets a valid access token for the specified client ID. |
| 69 It also has simple JavaScript methods that, after authenticated, |
| 70 goes to the Tasks API and gets the user's task lists and the corresponding t
asks. </p> |
| 60 | 71 |
| 61 <p class="note"><b>Note:</b> this script is NOT intented to be used in producti
on - it is just a very simple, limited and definitely not robust piece of code i
ntented to highlight the basic authentication and API calls.</p></li> | 72 <p class="note"><b>Note:</b> This script is NOT intented to be used in productio
n - it is just a very simple, limited and definitely not robust piece of code in
tented to highlight the basic authentication and API calls.</p></li> |
| 62 <li><p>Add a new method to the existing <a href="https://github.com/GoogleChrome
/chrome-app-codelab/blob/master/lab7_useridentification/angularjs/controller.js"
>controller.js</a> that, using the methods from the script of the previous step,
authenticates the user and imports his Google tasks into the Todo list: | 73 <li><p>Add a new method to the existing |
| 63 <pre> | 74 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7_use
ridentification/angularjs/controller.js">AngularJS controller.js</a> or |
| 75 <a href="https://github.com/GoogleChrome/chrome-app-codelab/blob/master/lab7_use
ridentification/javascript/controller.js">JavaScript controller.js</a> that, |
| 76 using the methods from the script of the previous step, |
| 77 authenticates the user and imports his Google tasks into the Todo list: |
| 78 </p> |
| 79 |
| 80 <tabs data-group="source"> |
| 81 |
| 82 <header tabindex="0" data-value="angular">Angular</header> |
| 83 <header tabindex="0" data-value="js">JavaScript</header> |
| 84 |
| 85 <content> |
| 86 <pre> |
| 64 $scope.importFromGTasks = function() { | 87 $scope.importFromGTasks = function() { |
| 65 var api = new TasksAPI(); | 88 var api = new TasksAPI(); |
| 66 var clientId = "<GET_YOURS_AT_https://code.google.com/apis/console>
"; | 89 var clientId = "<GET_YOURS_AT_https://code.google.com/apis/console>
"; |
| 67 api.authenticate(clientId, function() { | 90 api.authenticate(clientId, function() { |
| 68 api.getLists(function(result) { | 91 api.getLists(function(result) { |
| 69 console.log(result); | 92 console.log(result); |
| 70 if (!result || !result.items || result.items.length==0) { | 93 if (!result || !result.items || result.items.length==0) { |
| 71 throw "No task lists available"; | 94 throw "No task lists available"; |
| 72 } | 95 } |
| 73 var listId=result.items[0].id; | 96 var listId=result.items[0].id; |
| 74 api.getTasks(listId, function(tasks) { | 97 api.getTasks(listId, function(tasks) { |
| 75 console.log(tasks); | 98 console.log(tasks); |
| 76 for (var j=0; j<tasks.items.length; j++) { | 99 for (var j=0; j<tasks.items.length; j++) { |
| 77 $scope.$apply(function() { | 100 $scope.$apply(function() { |
| 78 $scope.todos.push({text:tasks.items[j].title, done:tasks.items[j].st
atus!="needsAction"}); | 101 $scope.todos.push({text:tasks.items[j].title, done:tasks.items[j].st
atus!="needsAction"}); |
| 79 }); | 102 }); |
| 80 } | 103 } |
| 81 }); | 104 }); |
| 82 }); | 105 }); |
| 83 }); | 106 }); |
| 84 } | 107 } |
| 85 </pre> </p> | 108 </pre> |
| 109 </content> |
| 110 <content> |
| 111 <pre> |
| 112 document.getElementById('importGTasks').addEventListener('click', function() { |
| 113 var api = new TasksAPI(); |
| 114 var clientId = "<GET_YOURS_AT_https://code.google.com/apis/console&g
t;"; |
| 115 api.authenticate(clientId, function() { |
| 116 api.getLists(function(result) { |
| 117 console.log(result); |
| 118 if (!result || !result.items || result.items.length==0) { |
| 119 throw "No task lists available"; |
| 120 } |
| 121 var listId=result.items[0].id; |
| 122 api.getTasks(listId, function(tasks) { |
| 123 console.log(tasks); |
| 124 for (var j=0; j<tasks.items.length; j++) { |
| 125 model.addTodo(tasks.items[j].title, tasks.items[j].status!='needsAct
ion'); |
| 126 } |
| 127 }); |
| 128 }); |
| 129 }); |
| 130 }); |
| 131 </pre> |
| 132 |
| 133 </tabs> |
| 86 | 134 |
| 87 <p>Replace the following line in the code above: | 135 <p>Replace the following line in the code above: |
| 88 <pre> | 136 <pre> |
| 89 var clientId = "<GET_YOURS_AT_https://code.google.com/apis/console>
"; | 137 var clientId = "<GET_YOURS_AT_https://code.google.com/apis/console>
"; |
| 90 </pre> | 138 </pre> |
| 91 with your own project's Client ID that you got from the Google API Console.
Should look like this: | 139 with your own project's Client ID that you got from the Google API Console. |
| 140 Should look like this: |
| 92 <pre> | 141 <pre> |
| 93 var clientId = "xxxxxxxxxxxxxx.apps.googleusercontent.com"; | 142 var clientId = "xxxxxxxxxxxxxx.apps.googleusercontent.com"; |
| 94 </pre></p></li> | 143 </pre></p></li> |
| 95 <li><p>Now we just need a button that starts the import process. Update the <cod
e>index.html</code> to include <code>gapi_tasks.js</code> and add a new button t
o call <code>importFromGTasks</code>: | 144 <li><p>Now we just need a button that starts the import process. Update the <cod
e>index.html</code> to include <code>gapi_tasks.js</code> and add a new button t
o call <code>importFromGTasks</code>: |
| 96 <pre> | 145 </p> |
| 146 |
| 147 <tabs data-group="source"> |
| 148 |
| 149 <header tabindex="0" data-value="angular">Angular</header> |
| 150 <header tabindex="0" data-value="js">JavaScript</header> |
| 151 |
| 152 <content> |
| 153 <pre> |
| 97 <script src="gapi_tasks.js"></script> | 154 <script src="gapi_tasks.js"></script> |
| 98 ... | 155 ... |
| 99 <button ng-click="importFromGTasks()">import tasks from GTasks&l
t;/button> | 156 <button ng-click="importFromGTasks()">import tasks from GTasks&l
t;/button> |
| 100 </pre></p></li> | 157 </pre> |
| 158 </content> |
| 159 <content> |
| 160 <pre> |
| 161 <button id="importGTasks">import tasks from GTasks</button> |
| 162 ... |
| 163 <script src="gapi_tasks.js"></script> |
| 164 </pre> |
| 165 </content> |
| 166 |
| 167 </tabs></li> |
| 101 </ol> | 168 </ol> |
| 102 | 169 |
| 103 <p class="note"><b>Note:</b> If you get stuck and want to see the app in action
, | 170 <h3 id="results">Check the results</h3> |
| 104 go to <code>chrome://extensions</code>, load the unpacked <a href="https://githu
b.com/GoogleChrome/chrome-app-codelab/tree/master/lab7_useridentification">lab7
app</a>, | 171 |
| 172 <p>If you get stuck and want to see the app in action, |
| 173 go to <code>chrome://extensions</code>, |
| 174 load the unpacked |
| 175 <a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab7_use
ridentification/angularjs">AngularJS app</a> or |
| 176 <a href="https://github.com/GoogleChrome/chrome-app-codelab/tree/master/lab7_use
ridentification/javascript">JavaScript app</a>, |
| 105 and launch the app from a new tab.</p> | 177 and launch the app from a new tab.</p> |
| 106 | 178 |
| 107 <h1 id="what_39_s_next_">What's next?</h1> | 179 <h2 id="you_should_also_read">You should also read</h2> |
| 108 | 180 |
| 109 <p>In <a href="app_codelab8_webresources.html">lab8_webresources</a>, | 181 <p><a href="http://developer.chrome.com/trunk/apps/app_identity.html">Identify U
ser</a> tutorial</p> |
| 182 |
| 183 <h2 id="what_39_s_next_">What's next?</h2> |
| 184 |
| 185 <p>In <a href="app_codelab8_webresources.html">7 - Access Web Resources</a>, |
| 110 you will learn how to load and show images from a remote URL.</p> | 186 you will learn how to load and show images from a remote URL.</p> |
| 111 | 187 |
| 112 <p class="note"><b>Note:</b> Up until now, the code in each lab builds upon the
previous lab code sample. | 188 <p class="note"><b>Note:</b> Up until now, the code in each lab builds upon the
previous lab code sample. |
| 113 We've decided not to include the user identification code changes in the rem
ainder of the lab since the <code>identity API</code> is still experimental and
as such it would prevent you from publishing your final code to the Chrome Web S
tore.</p> | 189 We've decided not to include the user identification code changes in the rem
ainder of the lab since the <code>identity API</code> is still experimental and
as such it would prevent you from publishing your final code to the Chrome Web S
tore.</p> |
| OLD | NEW |