In this tutorial, you build the code for and run a single-page application (SPA)
with Blockstack and Vue.js. Once the application is running, you take a tour
through the applications’ Blockstack functionality. You’ll learn how it manages
authentiation using a Blockstack ID and how it stores information associated
with that ID using Blockstack Storage (Gaia).
* TOC
{:toc}
{% include note.html content="This tutorial was written on macOS High Sierra 10.13.4. If you use a Windows or Linux system, you can still follow along. However, you will need to \"translate\" appropriately for your operating system. Additionally, this tutorial assumes you are accessing the Blockstack Browser web application via Chrome. The application you build will also work with a local installation and/or with browsers other than Chrome. " %}
If you prefer a video, you can view <ahref="https://www.youtube.com/embed/oyvg-h0obFw"target="\_blank">a video of the tutorial</a>.
## About this tutorial and the prerequisites you need
For this tutorial, we will use the following tools:
*`npm` to manage dependencies and scripts
*`browserify` to compile node code into browser-ready code
*`blockstack.js` to authenticate the user and work with the user’s identity/profile information
At minimum, Blockstack requires macOS High Sierra. This tutorial was written for a user running macOS High Sierra 10.13.4. The application you build is a Vue.js application that is completely decentralized and server-less. While not strictly required to follow along, basic familiarity with Vue.js is helpful.
This path will be different for you, but double-check the last part to ensure that you're in the directory into which you cloned and in which you ran `npm install`.
> * The `iss` property is a decentralized identifier or `did`. This identifies you and your name to the application. The specific `did` is a `btc-addr`.
> * The Blockstack JWT implementation is different from other implementations because of the underlying cryptography we employ. There are libraries in [Javascript](https://github.com/blockstack/jsontokens-js) and [Ruby](https://github.com/blockstack/ruby-jwt-blockstack) available on the Blockstack Github to allow you to work with these tokens.
When the Blockstack node receives the `authRequest`, it generates a session token
and returns an authentication response to the application. This response is
similar to the `authRequest` above in that the `authResponse` includes a private key
intended only for the application. This allows the application to encrypt data
on your personal Blockstack storage.
After the completion of this process, the user is logged in.
Now, go to the underlying `blockstack-todo` code you cloned or downloaded. Sign
in and sign out is handled in each of these files:
| File | Description |
|-----------------|-------------|
| `App.vue ` | Handles the `authResponse`. |
| `Landing.vue ` | Generates the `authRequest`. |
| `Dashboard.vue` | Handles sign out. |
The `src/components/Landing.vue` code calls a [`redirectToSignIn()`](https://blockstack.github.io/blockstack.js#redirectToSignIn) function which generates the `authRequest` and redirects the user to the Blockstack authenticator:
```js
signIn () {
const blockstack = this.blockstack
blockstack.redirectToSignIn()
}
```
Once the user authenticates, the application handles the `authResponse` in the `src/App.vue` file. :
```js
if (blockstack.isUserSignedIn()) {
this.user = blockstack.loadUserData().profile
} else if (blockstack.isSignInPending()) {
blockstack.handlePendingSignIn()
.then((userData) => {
window.location = window.location.origin
})
}
```
If [`blockstack.isUserSignedIn()`](https://blockstack.github.io/blockstack.js/#isusersignedin) is true, the user was previously signed in so Blockstack pulls the data from the browser and uses it in our application. If the check on [`blockstack.isSignInPending()`](https://blockstack.github.io/blockstack.js/#issigninpending) is true, a previous `authResponse` was sent to the application but hasn't been processed yet. The `handlePendingSignIn()` function processes any pending sign in.
Signout is handled in `src/components/Dashboard.vue`.
```js
signOut () {
this.blockstack.signUserOut(window.location.href)
}
```
The method allows the application creator to decide where to redirect the user upon Sign Out:
## Working with the application
Now, trying adding a few itmes to the todo list. For example, try making a list of applications you want to see built on top of Blockstack:
![](images/make-a-list.png)
Each list is immediately stored in the Gaia Hub linked to your Blockstack ID.
For more information about the Gaia hub, see the [hub
repository](https://github.com/blockstack/gaia). You can fetch the `todos.json`
file you just added by opening the Javascript console and running the following
The code needs to read the Todo items from the storage with the [`blockstack.getFile()`](https://blockstack.github.io/blockstack.js/#getfile) method which returns a promise:
```js
fetchData () {
const blockstack = this.blockstack
blockstack.getFile(STORAGE_FILE) // decryption is enabled by default
.then((todosText) => {
var todos = JSON.parse(todosText || '[]')
todos.forEach(function (todo, index) {
todo.id = index
})
this.uidCount = todos.length
this.todos = todos
})
},
```
The `todos` data is retrieved from the promise.
## Summary
You now have everything you need to construct complex applications complete with authentication and storage on the Decentralized Internet. Why not try coding [a sample application that accesses multiple profiles](blockstack_storage.html).
If you would like to explore the Blockstack APIs, you can visit the [Blockstack Core API](https://core.blockstack.org/) documentation or the [Blockstack JS API](https://blockstack.github.io/blockstack.js).