1 | # Simple OAuth2
|
2 |
|
3 | Node.js client library for [Oauth2](http://oauth.net/2/).
|
4 |
|
5 | OAuth2 lets users grant the access to the desired resources to third party applications,
|
6 | giving them the possibility to enable and disable those accesses whenever they want.
|
7 |
|
8 | Simple OAuth2 supports the following flows.
|
9 |
|
10 | * Authorization Code Flow (for apps with servers that can store persistent information).
|
11 | * Password Credentials (when previous flow can't be used or during development).
|
12 | * [Client Credentials Flow](http://tools.ietf.org/html/draft-ietf-oauth-v2-31#section-4.4) (the client can request an access token using only its client credentials)
|
13 |
|
14 | ## Requirements
|
15 |
|
16 | Node client library is tested against Node ~0.8.x
|
17 |
|
18 |
|
19 | ## Installation
|
20 |
|
21 | Install the client library using [npm](http://npmjs.org/):
|
22 |
|
23 | $ npm install simple-oauth2
|
24 |
|
25 | Install the client library using git:
|
26 |
|
27 | $ git clone git://github.com/andrearegianto/simple-oauth2.git
|
28 | $ cd simple-oauth2
|
29 | $ npm install
|
30 |
|
31 |
|
32 | ## Getting started
|
33 |
|
34 | ### Express and Github example
|
35 |
|
36 | ```javascript
|
37 | var express = require('express'),
|
38 | app = express();
|
39 |
|
40 | var OAuth2 = require('simple-oauth2')({
|
41 | clientID: CLIENT_ID,
|
42 | clientSecret: CLIENT_SECRET,
|
43 | site: 'https://github.com/login',
|
44 | tokenPath: '/oauth/access_token'
|
45 | });
|
46 |
|
47 | // Authorization uri definition
|
48 | var authorization_uri = OAuth2.AuthCode.authorizeURL({
|
49 | redirect_uri: 'http://localhost:3000/callback',
|
50 | scope: 'notifications',
|
51 | state: '3(#0/!~'
|
52 | });
|
53 |
|
54 | // Initial page redirecting to Github
|
55 | app.get('/auth', function (req, res) {
|
56 | res.redirect(authorization_uri);
|
57 | });
|
58 |
|
59 | // Callback service parsing the authorization token and asking for the access token
|
60 | app.get('/callback', function (req, res) {
|
61 | var code = req.query.code;
|
62 | console.log('/callback');
|
63 | OAuth2.AuthCode.getToken({
|
64 | code: code,
|
65 | redirect_uri: 'http://localhost:3000/callback'
|
66 | }, saveToken);
|
67 |
|
68 | function saveToken(error, result) {
|
69 | if (error) { console.log('Access Token Error', error.message); }
|
70 | token = OAuth2.AccessToken.create(result);
|
71 | }
|
72 | });
|
73 |
|
74 | app.get('/', function (req, res) {
|
75 | res.send('Hello World');
|
76 | });
|
77 |
|
78 | app.listen(3000);
|
79 |
|
80 | console.log('Express server started on port 3000');
|
81 | ```
|
82 |
|
83 | Credits to [@lazybean](https://github.com/lazybean)
|
84 |
|
85 | ### Authorization Code flow
|
86 |
|
87 | The Authorization Code flow is made up from two parts. At first your application asks to
|
88 | the user the permission to access their data. If the user approves the OAuth2 server sends
|
89 | to the client an authorization code. In the second part, the client POST the authorization code
|
90 | along with its client secret to the Lelylan in order to get the access token.
|
91 |
|
92 | ```javascript
|
93 | // Set the client credentials and the OAuth2 server
|
94 | var credentials = {
|
95 | clientID: '<client-id>',
|
96 | clientSecret: '<client-secret>',
|
97 | site: 'https://api.oauth.com'
|
98 | };
|
99 |
|
100 | // Initialize the OAuth2 Library
|
101 | var OAuth2 = require('simple-oauth2')(credentials);
|
102 |
|
103 | // Authorization OAuth2 URI
|
104 | var authorization_uri = OAuth2.AuthCode.authorizeURL({
|
105 | redirect_uri: 'http://localhost:3000/callback',
|
106 | scope: '<scope>',
|
107 | state: '<state>'
|
108 | });
|
109 |
|
110 | // Redirect example using Express (see http://expressjs.com/api.html#res.redirect)
|
111 | res.redirect(authorization_uri);
|
112 |
|
113 | // Get the access token object (the authorization code is given from the previous step).
|
114 | var token;
|
115 | OAuth2.AuthCode.getToken({
|
116 | code: '<code>',
|
117 | redirect_uri: 'http://localhost:3000/callback'
|
118 | }, saveToken);
|
119 |
|
120 | // Save the access token
|
121 | function saveToken(error, result) {
|
122 | if (error) { console.log('Access Token Error', error.message); }
|
123 | token = OAuth2.AccessToken.create(result);
|
124 | });
|
125 | ```
|
126 |
|
127 |
|
128 | ### Password Credentials Flow
|
129 |
|
130 | This flow is suitable when the resource owner has a trust relationship with the
|
131 | client, such as its computer operating system or a highly privileged application.
|
132 | Use this flow only when other flows are not viable or when you need a fast way to
|
133 | test your application.
|
134 |
|
135 | ```javascript
|
136 | // Get the access token object.
|
137 | var token;
|
138 | OAuth2.Password.getToken({
|
139 | username: 'username',
|
140 | password: 'password'
|
141 | }, saveToken);
|
142 |
|
143 | // Save the access token
|
144 | function saveToken(error, result) {
|
145 | if (error) { console.log('Access Token Error', error.message); }
|
146 | token = OAuth2.AccessToken.create(result);
|
147 | });
|
148 | ```
|
149 |
|
150 | ### Client Credentials Flow
|
151 |
|
152 | This flow is suitable when client is requesting access to the protected resources under its control.
|
153 |
|
154 | ```javascript
|
155 | // Get the access token object.
|
156 | var token;
|
157 | var credentials = {
|
158 | clientID: '<client-id>',
|
159 | clientSecret: '<client-secret>',
|
160 | site: 'https://api.oauth.com'
|
161 | };
|
162 |
|
163 | // Initialize the OAuth2 Library
|
164 | var OAuth2 = require('simple-oauth2')(credentials);
|
165 |
|
166 | // Get the access token object for the client
|
167 | OAuth2.Client.getToken(saveToken);
|
168 |
|
169 | // Save the access token
|
170 | function saveToken(error, result) {
|
171 | if (error) { console.log('Access Token Error', error.message); }
|
172 | token = OAuth2.AccessToken.create(result);
|
173 | });
|
174 | ```
|
175 |
|
176 | ### Access Token object
|
177 |
|
178 | When a token expires we need to refresh it. Simple OAuth2 offers the
|
179 | AccessToken class that add a couple of useful methods to refresh the
|
180 | access token when it is expired.
|
181 |
|
182 | ```javascript
|
183 | // Sample of a JSON access token (you got it through previous steps)
|
184 | var token = {
|
185 | 'access_token': '<access-token>',
|
186 | 'refresh_token': '<refresh-token>',
|
187 | 'expires_in': '7200'
|
188 | };
|
189 |
|
190 | // Create the access token wrapper
|
191 | var token = OAuth2.AccessToken.create(token);
|
192 |
|
193 | // Check if the token is expired. If expired it is refreshed.
|
194 | if (token.expired()) {
|
195 | token.refresh(function(error, result) {
|
196 | token = result;
|
197 | })
|
198 | }
|
199 | ```
|
200 |
|
201 |
|
202 | ### Errors
|
203 |
|
204 | Exceptions are raised when a 4xx or 5xx status code is returned.
|
205 |
|
206 | HTTPError
|
207 |
|
208 | Through the error message attribute you can access the JSON representation
|
209 | based on HTTP `status` and error `message`.
|
210 |
|
211 | ```javascript
|
212 | OAuth2.AuthCode.getToken(function(error, token) {
|
213 | if (error) { console.log(error.message); }
|
214 | });
|
215 | // => { "status": "401", "message": "Unauthorized" }
|
216 | ```
|
217 |
|
218 |
|
219 | ### Configurations
|
220 |
|
221 | Simple OAuth2 accepts an object with the following valid params.
|
222 |
|
223 | * `clientID` - Required registered Client ID.
|
224 | * `clientSecret` - Required registered Client secret.
|
225 | * `site` - Required OAuth2 server site.
|
226 | * `authorizationPath` - Authorization path for the OAuth2 server. Defaults to `/oauth/authorize`.
|
227 | * `tokenPath` - Access token path for the OAuth2 server. Defaults to `/oauth/token`.
|
228 | * `useBasicAuthorizationHeader` - Whether or not the `Authorization: Basic ...` header is set on the request.
|
229 | Defaults to `true`.
|
230 | * `clientSecretParameterName` - Parameter name for the client secret. Defaults to `client_secret`.
|
231 |
|
232 | ```javascript
|
233 | // Set the configuration settings
|
234 | var credentials = {
|
235 | clientID: '<client-id>',
|
236 | clientSecret: '<client-secret>',
|
237 | site: 'https://www.oauth2.com',
|
238 | authorizationPath: '/oauth2/authorization',
|
239 | tokenPath: '/oauth2/access_token'
|
240 | };
|
241 |
|
242 | // Initialize the OAuth2 Library
|
243 | var OAuth2 = require('simple-oauth2')(credentials);
|
244 | ```
|
245 |
|
246 |
|
247 | ## Contributing
|
248 |
|
249 | Fork the repo on github and send a pull requests with topic branches. Do not forget to
|
250 | provide specs to your contribution.
|
251 |
|
252 |
|
253 | ### Running specs
|
254 |
|
255 | * Fork and clone the repository (`dev` branch).
|
256 | * Run `npm install` for dependencies.
|
257 | * Run `make test` to execute all specs.
|
258 | * Run `make test-watch` to auto execute all specs when a file change.
|
259 |
|
260 |
|
261 | ## Coding guidelines
|
262 |
|
263 | Follow [github](https://github.com/styleguide/) guidelines.
|
264 |
|
265 |
|
266 | ## Feedback
|
267 |
|
268 | Use the [issue tracker](http://github.com/andreareginato/simple-oauth2/issues) for bugs.
|
269 | [Mail](mailto:andrea.reginato@.gmail.com) or [Tweet](http://twitter.com/andreareginato) us
|
270 | for any idea that can improve the project.
|
271 |
|
272 |
|
273 | ## Links
|
274 |
|
275 | * [GIT Repository](http://github.com/andreareginato/simple-oauth2)
|
276 | * [Documentation](http://andreareginato.github.com/simple-oauth2)
|
277 |
|
278 |
|
279 | ## Authors
|
280 |
|
281 | [Andrea Reginato](http://twitter.com/andreareginato)
|
282 |
|
283 |
|
284 | ## Contributors
|
285 |
|
286 | Special thanks to the following people for submitting patches.
|
287 |
|
288 |
|
289 | ## Changelog
|
290 |
|
291 | See [CHANGELOG](https://github.com/andreareginato/simple-oauth2/blob/master/CHANGELOG.md)
|
292 |
|
293 |
|
294 | ## Copyright
|
295 |
|
296 | Copyright (c) 2013 [Lelylan](http://lelylan.com).
|
297 |
|
298 | This project is released under the [MIT License](http://opensource.org/licenses/MIT).
|