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