/images/resources/code-examples/code-examples-angular.jpg

Angular SPA using Assisted Token Flow

On this page

Note

The example uses the Curity Identity Server, but you can run the code against any standards-based authorization server.

Overview

An example Angular application capable of acquiring an access token from the Curity Identity Server using the assisted token flow. The example code contains a Single Page Application for acquiring the token and an example API which can be called from the SPA using the access token.

Best Practice Update

For best results and strongest security it is no longer recommended to implement OAuth for your production SPAs solely in Javascript. See the SPA security best practices for an alternative design.

The assisted token flow may also be impacted by recent same-site cookie restrictions, if the user agent no longer sends the required cookies. See the OAuth cookie best practices article for further information.

Configure the Identity Server

In the Curity Identity Server, create an OAuth client with the following details, and also ensure that at least one working authenticator is configured against the client:

  • Client ID: client-assisted-example
  • Capabilities: Assisted Token Flow + Implicit Flow
  • Allowed Origins: http://localhost:4200
  • Redirect URI: http://localhost:4200
  • OAuth + OpenID Settings / Scope: openid

Configure the SPA

The Angular SPA can be downloaded from the GitHub link on this page and will then run athttp://localhost:4200 by default. Edit the environment.ts file in the SPA and set details to match your environment:

javascript
12345678
export const environment = {
production: false,
issuer: 'https://localhost:8443/',
clientId: 'client-assisted-example',
apiUrl: 'http://127.0.0.1:8100',
authServerOrigin: 'http://127.0.0.1:8100',
openIdConfigurationUrl: 'oauth/v2/oauth-anonymous/.well-known/openid-configuration'
};

The SPA will use the Assisted Token Endpoint from the Curity Identity Server, and will download a library from a URL such as this at runtime:

  • https://localhost:8443/oauth/v2/oauth-assisted-token/resources/js/assisted-token.min.js

The SPA will then use the window.curity.token.assistant Javascript object to perform OAuth operations, via the AssistantService TypeScript class.

Run the SPA

Now that the setup is complete you can run npm install then npm start to start the server, then browse to the SPA at http://localhost:4200. When the page loads, it makes an initial full screen redirect to the Identity Server in order to act as a user gesture, so that SSO cookies are then persisted by the browser. This is done in the assistant.service.ts source file in the checkAuthorization method:

javascript
12
this.window.location.href = this.config.authorization_endpoint + `?response_type=id_token&scope=openid&client_id=${environment.clientId}` +
`&redirect_uri=${this.window.origin}&prompt=none&nonce=${nonce}`;

Perform a Login

Next click the Login button to trigger sign in via an iframe, to prompt the end user to authenticate. The sample then uses secure iframing to invoke a login window without disrupting the current state within the SPA:

Angular Sign In

Triggering the login request only requires a single line of code when using the assisted token library, after which tokens are returned to the SPA:

javascript
123
this.assistantService.getAssistant().loginIfRequired().then((msg) => {
this.userToken = this.assistantService.getAssistant().getAuthHeader();
}

Once login is complete, an authenticated session begins, and this is represented by an SSO cookie that the Identity Server issues to the SPA. This cookie is used by the assisted token library to retrieve tokens silently while the user's authenticated session remains valid.

Call an API from the Angular SPA

After user sign in, the code sample provides a minimal screen as follows, to show the token returned from login and sent to the sample's API:

Angular API Calls

The sample uses the Angular HTTP Client to call the API and note that the assisted token library manages overriding the XmlHttpRequest and adding the access token to the Authorization header in the correct manner.

javascript
1234567891011
callApi() {
const tokenAssistant = this.assistantService.getAssistant();
const isUserAuthenticated = tokenAssistant.isAuthenticated() && !this.tokenAssistant.isExpired();
if (isUserAuthenticated) {
this.http.get(environment.apiUrl + '/api').subscribe(
this.apiResponse = response.data;
}
else {
tokenAssistant.loginIfRequired().then((token) => {
this.callApi();
}

The assisted token library also helps to deal with access token expiry conditions. If a token is expired or a 401 response is received from the API, the SPA can call loginIfRequired again to attempt to silently refresh the token, or to prompt the user to re-authenticate if the SSO cookie has expired.

API Cross Origin Request Handling

The Angular code example includes a simple Node.js API which runs at http://localhost:8100 and is implemented in the server.js file. The API operation simply echoes the token back to the UI for display, but the API code shows how to set API response headers so that the browser is allowed to make cross origin calls to the API:

javascript
1234567891011121314
var origin = request.headers["origin"];
if (request.method === 'OPTIONS') {
responseHeaders['Access-Control-Allow-Origin'] = origin;
responseHeaders['Access-Control-Allow-Methods'] = "GET, HEAD, OPTIONS";
responseHeaders['Access-Control-Allow-Headers'] = 'Authorization, WWW-Authenticate, Content-Type';
responseHeaders["Access-Control-Allow-Credentials"] = "true";
responseHeaders["Allow"] = "GET, HEAD, OPTIONS";
response.writeHead(200, responseHeaders);
response.end();
}
else {
responseHeaders["Access-Control-Allow-Origin"] = origin;
responseHeaders["Access-Control-Allow-Credentials"] = "true";
}

Lifecycle Events

The Angular SPA is only a basic sample to show how to fit the Assisted Token flow into a Angular coding style. For further details on dealing with lifecycle events, see the Javascript Assisted Token Sample, which covers aspects such as token refresh and multi tab browsing.

Conclusion

The Assisted Token Flow can be easily integrated into a Angular SPA, and adapted to the Angular coding style. For further programming details, see the Assisted Token Library API Reference.

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial