Skip to content

Commit 3ec25a2

Browse files
rotembrmotyd
authored andcommitted
Add refresh token support and self-servive manager
1 parent b5267c9 commit 3ec25a2

32 files changed

+4195
-373
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
language: node_js
22

3+
node_js:
4+
- "6"
5+
36
notifications:
47
email:
58
on_success: always

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Read the [official documentation](https://console.ng.bluemix.net/docs/services/a
3232

3333
## Requirements
3434
* npm 4.+
35-
* node 4.+
35+
* node 6.+
3636

3737
## Installation
3838
```
@@ -92,6 +92,7 @@ app.get("/api/protected",
9292
appIdAuthContext.accessTokenPayload; // Decoded access_token JSON
9393
appIdAuthContext.identityToken; // Raw identity_token
9494
appIdAuthContext.identityTokenPayload; // Decoded identity_token JSON
95+
appIdAuthContext.refreshToken // Raw refresh_token
9596

9697
// Or use user object provided by passport.js
9798
var username = req.user.name || "Anonymous";
@@ -108,7 +109,7 @@ app.listen(port, function(){
108109
```
109110

110111
#### Protecting web applications using WebAppStrategy
111-
WebAppStrategy is based on the OAuth2 authorization_code grant flow and should be used for web applications that use browsers. The strategy provides tools to easily implement authentication and authorization flows. When WebAppStrategy provides mechanisms to detect unauthenticated attempts to access protected resources. The WebAppStrategy will automatically redirect user's browser to the authentication page. After successful authentication user will be taken back to the web application's callback URL (redirectUri), which will once again use WebAppStrategy to obtain access and identity tokens from App ID service. After obtaining these tokens the WebAppStrategy will store them in HTTP session under WebAppStrategy.AUTH_CONTEXT key. In a scalable cloud environment it is recommended to persist HTTP sessions in a scalable storage like Redis to ensure they're available across server app instances.
112+
WebAppStrategy is based on the OAuth2 authorization_code grant flow and should be used for web applications that use browsers. The strategy provides tools to easily implement authentication and authorization flows. When WebAppStrategy provides mechanisms to detect unauthenticated attempts to access protected resources. The WebAppStrategy will automatically redirect user's browser to the authentication page. After successful authentication user will be taken back to the web application's callback URL (redirectUri), which will once again use WebAppStrategy to obtain access, identity and refresh tokens from App ID service. After obtaining these tokens the WebAppStrategy will store them in HTTP session under WebAppStrategy.AUTH_CONTEXT key. In a scalable cloud environment it is recommended to persist HTTP sessions in a scalable storage like Redis to ensure they're available across server app instances.
112113

113114
```JavaScript
114115
const express = require('express');
@@ -223,7 +224,16 @@ app.get(LOGIN_ANON_URL, passport.authenticate(WebAppStrategy.STRATEGY_NAME, {
223224
}));
224225
```
225226

226-
As mentioned previously the anonymous access_token and identity_token will be automatically persisted in HTTP session by App ID SDK. You can retrieve them from HTTP session via same mechanisms as regular tokens. Access and identity tokens will be kept in HTTP session and will be used until either them or HTTP session expires.
227+
As mentioned previously the anonymous access_token, identity_token and refresh_token (optional) will be automatically persisted in HTTP session by App ID SDK. You can retrieve them from HTTP session via same mechanisms as regular tokens. Access and identity tokens will be kept in HTTP session and will be used until either them or HTTP session expires.
228+
229+
### Refresh Token
230+
Refresh Token may be used to acquire new access and identity tokens without the need to re-authenticate. Refresh Token is usually configured to have longer expiration than access token. Refresh Token is optional and can be configured in your AppID Dashboard.
231+
232+
After a successful login, in addition to access_token and identity_token, a refresh_token will be persisted in the HTTP session as well.
233+
234+
You may persist the refresh_token in any method you'd like. By doing so, you can avoid your users login after the HTTP session has expired as long as the refresh_token is valid. `web-app-sample-server.js` contains an example of storing a refresh-token in a cookie and how to use it.
235+
236+
In order to use the persisted refresh_token, you need to call `webAppStrategy.refreshTokens(request, refreshToken)`. `refreshTokens()` returns a Promise. After the Promise has resolved, the user will be authenticated and new tokens will be generated and persistent in the HTTP session like in a classic login. If the Promise is rejected, the user won't be authenticated.
227237

228238
### User profile attributes
229239
Use the user UserAttributeManager to store and retrieve attribute of the user.

lib/appid-sdk.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ const Log4js = require("log4js");
1515
const APIStrategy = require("./strategies/api-strategy");
1616
const WebAppStrategy = require("./strategies/webapp-strategy");
1717
const UserAttributeManager = require("./attribute-manager/user-attribute-manager");
18+
const SelfServiceManager = require("./self-service/self-service-manager");
19+
const UnauthorizedException = require("./attribute-manager/unauthorized-exception");
1820

1921
const logger = Log4js.getLogger("appid-sdk");
2022
logger.info("Initialized");
2123

2224
module.exports = {
2325
APIStrategy: APIStrategy,
2426
WebAppStrategy: WebAppStrategy,
25-
UserAttributeManager: UserAttributeManager
26-
};
27-
28-
29-
27+
SelfServiceManager: SelfServiceManager,
28+
UserAttributeManager: UserAttributeManager,
29+
UnauthorizedException: UnauthorizedException
30+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module.exports = function UnauthorizedException() {
2+
3+
};

lib/attribute-manager/user-attribute-manager.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const log4js = require("log4js");
1515
const request = require("request");
1616
const Q = require("q");
1717
const _ = require("underscore");
18+
const UnauthorizedException = require("./unauthorized-exception");
19+
1820
const logger = log4js.getLogger("appid-user-attribute-manager");
1921

2022
const VCAP_SERVICES = "VCAP_SERVICES";
@@ -24,6 +26,7 @@ const VCAP_SERVICES_SERVICE_NAME2 = "AppID";
2426

2527
const USER_PROFILE_SERVER_URL = "profilesUrl";
2628
const ATTRIBUTES_ENDPOINT = "/api/v1/attributes";
29+
2730
function UserAttributeManager() {
2831
}
2932

@@ -114,7 +117,7 @@ function handleRequest(accessToken, attributeValue, method, url, action, deferre
114117
logger.error(err);
115118
return deferred.reject(new Error("Failed to " + action));
116119
} else if (response.statusCode === 401 || response.statusCode === 403) {
117-
return deferred.reject(new Error("Unauthorized"));
120+
return deferred.reject(new UnauthorizedException());
118121
} else if (response.statusCode === 404) {
119122
return deferred.reject(new Error("Not found"));
120123
} else if (response.statusCode >= 200 && response.statusCode < 300) {

0 commit comments

Comments
 (0)