Skip to content

Commit

Permalink
Merge pull request #742 from chenkie/master
Browse files Browse the repository at this point in the history
[new] Added Aurelia doc to client platforms
  • Loading branch information
ntotten committed Jan 17, 2016
2 parents 2c5fc4d + 6a4ae3b commit d92a952
Show file tree
Hide file tree
Showing 12 changed files with 260 additions and 0 deletions.
114 changes: 114 additions & 0 deletions articles/client-platforms/aurelia.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
---
title: Aurelia Tutorial
name: Aurelia
alias:
- aurelia
- aureliajs
language:
- Javascript
framework:
- Aurelia
image:
tags:
- quickstart
snippets:
configurehttp: client-platforms/aurelia/configurehttp
constructorexpiry: client-platforms/aurelia/constructorexpiry
dependencies: client-platforms/aurelia/dependencies
http: client-platforms/aurelia/http
jwtdecode: client-platforms/aurelia/jwtdecode
login: client-platforms/aurelia/login
logout: client-platforms/aurelia/logout
routing: client-platforms/aurelia/routing
setup: client-platforms/aurelia/setup
template: client-platforms/aurelia/template
tokenisexpired: client-platforms/aurelia/tokenisexpired
alias:
- aurelia
---

## Aurelia Tutorial

<%= include('../_includes/_package', {
pkgRepo: 'auth0-aurelia',
pkgBranch: 'master',
pkgPath: null,
pkgFilePath: null,
pkgType: 'js' + account.clientParam
}) %>

**If you have an existing application, follow the steps below.**

${include('./\_callback')}

### 1. Add the Auth0 Scripts

Add **Lock** to your `index.html` file and set the viewport.

${snippet(meta.snippets.dependencies)}

### 2. Import Dependencies and Set Up Auth0Lock

Later we'll see how to make authenticated HTTP requests, and for that we'll need `HttpClient` from `aurelia-fetch-client`. We also need to create a new instance of `Auth0Lock`.

${snippet(meta.snippets.setup)}

We also set the `isAuthenticated` property to false to start with, but this value will be changed later on to reflect the user's authentication status.

### 2. Set Up the Login and Logout Methods

The `login` and `logout` methods will be bound to button clicks in the template.

We first need to set up the buttons in our template. At the same time, we'll create a button that will be used for authenticated HTTP requests.

${snippet(meta.snippets.template)}

The `login` method will show the Lock widget and save the user's profile and JWT in local storage if authentication is successful and set `isAuthenticated` to true.

${snippet(meta.snippets.login)}

To log the user out, we just need to remove the their JWT and profile from local storage, and then set `isAuthenticated` to false.

${snippet(meta.snippets.logout)}

__Note:__ There are multiple ways of implementing login. The example above displays the Lock Widget. However you may implement your own login UI by changing the line `<script src="${widget_url_no_scheme}"></script>` to `<script src="//cdn.auth0.com/w2/auth0-6.7.js"></script>`.

### 3. Make Secure Calls to an API

To make secure calls to an API, attach the user's JWT as an `Authorization` header to the HTTP request. This is done in the `RequestInit` object as the second argument to the `fetch` call.

${snippet(meta.snippets.http)}

### 4. Configure All HTTP Calls to be Secure

If you wish to attach the user's JWT as an `Authorization` header on all HTTP calls, you can configure the `HttpClient` to do so.

${snippet(meta.snippets.configurehttp)}

You can then remove the `RequestInit` object (the second argument of `fetch`) from individual HTTP calls.

### 5. Optional: Decode the User's JWT to Check Expiry

Checking whether the user's JWT has expired is useful for conditionally showing or hiding elements and limiting access to certain routes. This can be done with the `jwt-decode` package and a simple function. First, install the package.

${snippet(meta.snippets.jwtdecode)}

Next, we can create a utilities file that will have a function that decodes the JWT and checks whether it has expired.

${snippet(meta.snippets.tokenisexpired)}

With this method in place, we can now call it in the constructor so that the user's authentication state is preserved if the page is refreshed.

${snippet(meta.snippets.constructorexpiry)}

### 6. Check Whether a Route Can Be Activated

Aurelia's `canActivate` method can be used to check whether a route can be navigated to. If the user's JWT has expired, we don't want them to be able to navigate to private routes.

${snippet(meta.snippets.routing)}

This hook will redirect the user to some other route--'public' in this case--if the user's JWT has expired.

### 7. All done!

You have completed the implementation of Login and Signup with Auth0 and Aurelia!
14 changes: 14 additions & 0 deletions snippets/client-platforms/aurelia/configurehttp.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
```js
// app.js

constructor(http) {
this.http = http;
this.http.configure(config => {
config.withDefaults({
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('id_token')
}
});
});
}
```
18 changes: 18 additions & 0 deletions snippets/client-platforms/aurelia/constructorexpiry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
```js
// app.js

import {tokenIsExpired} from './utils/tokenUtils';

constructor(http) {
this.http = http;

...

if(tokenIsExpired()) {
this.isAuthenticated = false;
}
else {
this.isAuthenticated = true;
}
}
```
7 changes: 7 additions & 0 deletions snippets/client-platforms/aurelia/dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
```html
<!-- Auth0 Lock script -->
<script src="${widget_url_no_scheme}"></script>

<!-- Setting the right viewport -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
```
13 changes: 13 additions & 0 deletions snippets/client-platforms/aurelia/http.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
```js
// app.js

getSecretThing() {
this.http.fetch('/api/protected-route', {
headers: {
'Authorization': 'Bearer ' + localStorage.getItem('id_token')
}
})
.then(response => response.json())
.then(data => this.secretThing = data.text);
}
```
3 changes: 3 additions & 0 deletions snippets/client-platforms/aurelia/jwtdecode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```bash
npm install jwt-decode
```
16 changes: 16 additions & 0 deletions snippets/client-platforms/aurelia/login.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
```js
// app.js

login() {
this.lock.show((err, profile, token) => {
if(err) {
console.log(err);
}
else {
localStorage.setItem('profile', JSON.stringify(profile));
localStorage.setItem('id_token', token);
this.isAuthenticated = true;
}
});
}
```
9 changes: 9 additions & 0 deletions snippets/client-platforms/aurelia/logout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
```js
// app.js

logout() {
localStorage.removeItem('profile');
localStorage.removeItem('id_token');
this.isAuthenticated = false;
}
```
19 changes: 19 additions & 0 deletions snippets/client-platforms/aurelia/routing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
```js
// private-route.js

import {Redirect} from 'aurelia-router';
import {tokenIsExpired} from './utils/tokenUtils';

export class Private {
message = "Hello from a private route.";

canActivate() {
if(tokenIsExpired()) {
return new Redirect('public');
}
else {
return true;
}
}
}
```
17 changes: 17 additions & 0 deletions snippets/client-platforms/aurelia/setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```js
// app.js

import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';

@inject(HttpClient)

export class App {
lock = new Auth0Lock('<%= account.clientId %>', '<%= account.namespace %>');
isAuthenticated = false;

constructor(http) {
this.http = http;
}
}
```
10 changes: 10 additions & 0 deletions snippets/client-platforms/aurelia/template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
```html
<!-- app.html -->
<template>
<button click.delegate="login()" if.bind="!isAuthenticate">Log In</button>
<button click.delegate="logout()" if.bind="isAuthenticated">Log Out</button>
<hr>
<button click.delegate="getSecretThing()" if.bind="isAuthenticated">Get Secret Thing</button>
<h3><%= '${secretThing}' %></h3>
</template>
```
20 changes: 20 additions & 0 deletions snippets/client-platforms/aurelia/tokenisexpired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
```js
// utils/tokenUtils.js

export function tokenIsExpired() {
let jwt = localStorage.getItem('id_token')
if(jwt) {
let jwtExp = jwt_decode(jwt).exp;
let expiryDate = new Date(0);
expiryDate.setUTCSeconds(jwtExp);

if(expiryDate < new Date()) {
return true;
}
}

else {
return false;
}
}
```

0 comments on commit d92a952

Please sign in to comment.