|
| 1 | +About |
| 2 | +===== |
| 3 | + |
| 4 | +This project provides an implementation of an client-side (implicit grant) |
| 5 | +OAuth 2.0 authorization flow. |
| 6 | + |
| 7 | + |
| 8 | +Features |
| 9 | +======== |
| 10 | + |
| 11 | +* Retrieval of a user's token using popups using the promise-based |
| 12 | + ``Token.getTokenByPopup()`` function, that presents the user with the |
| 13 | + authorization endpoint and returns the token asynchronously. |
| 14 | + |
| 15 | + (Implementation detail: A successfully obtained access token is handed back |
| 16 | + to the parent window via ``window.opener.postMessage`` and the source and |
| 17 | + origin of the sending window are verified by the parent.) |
| 18 | + |
| 19 | +* Access token verification using ``Token.verifyAsync``, by requesting token |
| 20 | + information from the authorization server, verifying that the token |
| 21 | + is valid and that it was generated by the current client (to prevent the |
| 22 | + confused deputy problem). |
| 23 | + |
| 24 | +* Storage and retrieval of tokens via the `Token.get` and `Token.set` |
| 25 | + calls in the `Token` service. |
| 26 | + |
| 27 | +* A preconfigured module for use with Google authentication. Check out the |
| 28 | + `example/js/demo.js <example/js/demo.js>`_ and |
| 29 | + `example/demo.html <example/js/demo.html>`_ for an example. |
| 30 | + |
| 31 | + |
| 32 | +Demo |
| 33 | +==== |
| 34 | + |
| 35 | +1. Run a static file server in the root directory (the one this file is in) |
| 36 | + on ``localhost:9000``. Python 2.X: ``python -m SimpleHTTPServer 9000``. |
| 37 | + |
| 38 | +2. Navigate to http://localhost:9000/example/demo.html. |
| 39 | + |
| 40 | + |
| 41 | +Google authentication quickstart |
| 42 | +================================ |
| 43 | + |
| 44 | +1. Create a project in the `Google APIs Console`_. In the "API Access" tab |
| 45 | + of the console, create an OAuth 2.0 client ID. When prompted, set the |
| 46 | + following settings: |
| 47 | + |
| 48 | + * **Application Type**: Web application. |
| 49 | + |
| 50 | + * **Site or Hostname**: The location at which you'll host these files. |
| 51 | + |
| 52 | + |
| 53 | +2. Edit authorized redirect URIs and JavaScript origins to match where you |
| 54 | + will be hosting your site. For example, let's say you're planning to |
| 55 | + host your site at https://example.com/. In that case, you might upload |
| 56 | + the `angular-oauth` code to https://example.com/angular-oauth/. You would |
| 57 | + then set your client ID settings accordingly: |
| 58 | + |
| 59 | + * **Authorized Redirect URIs**: |
| 60 | + https://example.com/angular-oauth/oauth2callback.html |
| 61 | + |
| 62 | + * **Authorized JavaScript Origins**: https://example.com |
| 63 | + |
| 64 | + |
| 65 | +3. Add ``googleOauth`` as a dependency to your app. |
| 66 | + |
| 67 | +4. Configure the ``TokenProvider`` with the following minimal settings: |
| 68 | + |
| 69 | + * `clientId`: (Required.) The client ID of your application, as given |
| 70 | + by your authentication server. |
| 71 | + |
| 72 | + * `redirectUri`: (Required.) The URI to redirect back to. You normally |
| 73 | + have to configure your authorization server to ensure that it redirects |
| 74 | + back to this point. |
| 75 | + |
| 76 | + * `scopes`: (Optional.) A list of scope tokens to describe the scope |
| 77 | + of the access request (more concretely, what information will be |
| 78 | + requested.) The scopes available for a given service are probably |
| 79 | + documented by the authorization server. |
| 80 | + |
| 81 | + For example:: |
| 82 | + |
| 83 | + config(function(TokenProvider) { |
| 84 | + TokenProvider.extendConfig({ |
| 85 | + clientId: '191261111313.apps.googleusercontent.com', |
| 86 | + redirectUri: 'http://localhost:9000/oauth2callback.html', |
| 87 | + scopes: ["https://www.googleapis.com/auth/userinfo.email"] |
| 88 | + }); |
| 89 | + }). |
| 90 | + |
| 91 | +5. After doing this, you can inject the ``Token`` service and enjoy its methods: |
| 92 | + |
| 93 | + * Request a token with ``Token.getTokenByPopup()``, which returns a |
| 94 | + promise that resolves to an object with an ``access_token`` item. |
| 95 | + |
| 96 | + * Verify that this is a valid token for your application by calling |
| 97 | + ``Token.verifyAsync(accessToken)``, which returns a promise that |
| 98 | + resolves to the response of `Google's TokenInfo service`_. |
| 99 | + |
| 100 | + * If you're able to verify the token, persist it in the browser using |
| 101 | + ``Token.set(accessToken)``. |
| 102 | + |
| 103 | + * Then when you need that token (e.g., to authorize a web service call), |
| 104 | + call ``Token.get()``. |
| 105 | + |
| 106 | + |
| 107 | +.. _Google APIs Console: https://code.google.com/apis/console/ |
| 108 | +.. _Google's TokenInfo service: https://developers.google.com/accounts/docs/OAuth2UserAgent#validatetoken |
| 109 | + |
| 110 | + |
| 111 | +Roadmap |
| 112 | +======= |
| 113 | + |
| 114 | +This is a work in progress! Don't use it in production. Here's some of what's |
| 115 | +yet to be done: |
| 116 | + |
| 117 | +* Security. While some mechanisms have been implemented to prevent token |
| 118 | + stealing, the project needs a systematic review of weaknesses. Some things |
| 119 | + to look out for are outlined in the OAuth specification, which also links |
| 120 | + to other resources. |
| 121 | + |
| 122 | + I also don't have intimate knowledge of the browser security model. The |
| 123 | + isolation of ``localStorage``. |
| 124 | + |
| 125 | +* Testing. Still lacking some confidence in this area, but soon enough |
| 126 | + I'll need to do something about the lack of tests. |
| 127 | + |
| 128 | +* Customization. Users may not always want to use popups. Perhaps taking |
| 129 | + over the entire browser window is more appropriate in some cases. (The |
| 130 | + reason for focusing on popup support is that tokens may expire, and ideally |
| 131 | + reauthentication should be able to occur without interrupting the state of |
| 132 | + the application.) |
| 133 | + |
| 134 | +* Browser compatibility and fault-tolerance. |
| 135 | + |
| 136 | + * I've tested all of one browser (Chrome). |
| 137 | + |
| 138 | + * The library currently depends on ``localStorage`` and doesn't take |
| 139 | + alternative measures if it's not available. |
| 140 | + |
| 141 | + * Unexpected behaviors are not handled gracefully. For example, if the |
| 142 | + user opens the callback page, they aren't presented with a friendly |
| 143 | + message explaining what might have happened. Ideally, the popup would |
| 144 | + notify the parent when it's closed (if that's even possible when the |
| 145 | + site in the popup has a different origin.) |
| 146 | + |
| 147 | +* It would be nice to support more authorization servers out of the box. |
0 commit comments