Browse Source

Search and replace auth to add UserSessions

Signed-off-by: Mary Anthony <mary@blockstack.com>
feat/clarity-updates
Mary Anthony 6 years ago
parent
commit
afd648c47f
  1. 6
      _browser/hello-blockstack.md
  2. 20
      _browser/todo-list.md
  3. 6
      _develop/add_auth.md
  4. 42
      _develop/overview_auth.md
  5. 77
      _develop/profiles.md
  6. 19
      _develop/storage.md
  7. 4
      _includes/sign_in.md
  8. 2
      _storage/hello-hub-choice.md
  9. 4
      overview_auth.md

6
_browser/hello-blockstack.md

@ -259,10 +259,10 @@ The application handles these situations as followed:
```js ```js
if (blockstack.isUserSignedIn()) { if (blockstack.isUserSignedIn()) {
var profile = blockstack.loadUserData().profile var profile = blockstack.UserSession.loadUserData().profile
showProfile(profile) showProfile(profile)
} else if (blockstack.isSignInPending()) { } else if (blockstack.UserSession.isSignInPending()) {
blockstack.handlePendingSignIn().then(function(userData) { blockstack.UserSession.handlePendingSignIn().then(function(userData) {
window.location = window.location.origin window.location = window.location.origin
}) })
} }

20
_browser/todo-list.md

@ -180,7 +180,7 @@ The `src/components/Landing.vue` code calls a [`redirectToSignIn()`](https://blo
```js ```js
signIn () { signIn () {
const blockstack = this.blockstack const blockstack = this.blockstack
blockstack.redirectToSignIn() blockstack.UserSession.redirectToSignIn()
} }
``` ```
@ -188,16 +188,16 @@ Once the user authenticates, the application handles the `authResponse` in the `
```js ```js
if (blockstack.isUserSignedIn()) { if (blockstack.isUserSignedIn()) {
this.user = blockstack.loadUserData().profile this.user = blockstack.UserSession.loadUserData().profile
} else if (blockstack.isSignInPending()) { } else if (blockstack.UserSession.isSignInPending()) {
blockstack.handlePendingSignIn() blockstack.UserSession.handlePendingSignIn()
.then((userData) => { .then((userData) => {
window.location = window.location.origin 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. 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.UserSession.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`. Signout is handled in `src/components/Dashboard.vue`.
@ -223,7 +223,7 @@ file you just added by opening the Javascript console and running the following
command: command:
```Javascript ```Javascript
blockstack.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)}) blockstack.UserSession.getFile("todos.json", { decrypt: true }).then((file) => {console.log(file)})
``` ```
You should see a JSON with the todos you just added: You should see a JSON with the todos you just added:
@ -283,22 +283,22 @@ todos: {
const blockstack = this.blockstack const blockstack = this.blockstack
// encryption is now enabled by default // encryption is now enabled by default
return blockstack.putFile(STORAGE_FILE, JSON.stringify(todos)) return blockstack.UserSession.putFile(STORAGE_FILE, JSON.stringify(todos))
}, },
deep: true deep: true
} }
``` ```
The `todos` JSON object is passed in and the The `todos` JSON object is passed in and the
[`blockstack.putFile()`](https://blockstack.github.io/blockstack.js/#putfile) [`blockstack.UserSession.putFile()`](https://blockstack.github.io/blockstack.js/#putfile)
method to store it in a Gaia Hub. method to store it in a Gaia Hub.
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: The code needs to read the Todo items from the storage with the [`blockstack.UserSession.getFile()`](https://blockstack.github.io/blockstack.js/#getfile) method which returns a promise:
```js ```js
fetchData () { fetchData () {
const blockstack = this.blockstack const blockstack = this.blockstack
blockstack.getFile(STORAGE_FILE) // decryption is enabled by default blockstack.UserSession.getFile(STORAGE_FILE) // decryption is enabled by default
.then((todosText) => { .then((todosText) => {
var todos = JSON.parse(todosText || '[]') var todos = JSON.parse(todosText || '[]')
todos.forEach(function (todo, index) { todos.forEach(function (todo, index) {

6
_develop/add_auth.md

@ -51,8 +51,8 @@ To check for the presence of this token, your app should call `UserSession.isSig
```js ```js
import * as blockstack from 'blockstack' import * as blockstack from 'blockstack'
if (blockstack.isSignInPending()) { if (blockstack.UserSession.isSignInPending()) {
blockstack.handlePendingSignIn() blockstack.UserSession.handlePendingSignIn()
.then(userData => { .then(userData => {
const profile = userData.profile const profile = userData.profile
}) })
@ -60,6 +60,8 @@ if (blockstack.isSignInPending()) {
``` ```
By default, these method use the `store_write` scope which allows the DApp to read the user profile and read/write user data for the DApp. To specify a different scope, use a <a href="https://blockstack.github.io/blockstack.js/classes/appconfig.html" target="\_blank">AppConfig</a> object.
### Custom flows ### Custom flows
Alternatively, you can generate your own transit private key and/or Alternatively, you can generate your own transit private key and/or

42
_develop/overview_auth.md

@ -2,7 +2,9 @@
layout: learn layout: learn
permalink: /:collection/:path.html permalink: /:collection/:path.html
--- ---
# Understand Blockstack Auth # Understand Blockstack Auth
{:.no_toc} {:.no_toc}
Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from an developer and user perspective. The following topics are covered: Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from an developer and user perspective. The following topics are covered:
@ -10,7 +12,6 @@ Blockstack Auth provides single sign on and authentication without third parties
* TOC * TOC
{:toc} {:toc}
## User experience flow ## User experience flow
Blockstack Auth is a bearer token-based authentication system. From an application user's perspective, Blockstack authentication is similar to legacy third-party authentication techniques that they're familiar with. Applications present users with a **Sign in with Blockstack** button. Blockstack Auth is a bearer token-based authentication system. From an application user's perspective, Blockstack authentication is similar to legacy third-party authentication techniques that they're familiar with. Applications present users with a **Sign in with Blockstack** button.
@ -18,23 +19,22 @@ Blockstack Auth is a bearer token-based authentication system. From an applicati
![](images/signwithblockstack.png) ![](images/signwithblockstack.png)
Assume a user, Alice, clicks the **Sign in with Blockstack** button on an app. She is Assume a user, Alice, clicks the **Sign in with Blockstack** button on an app. She is
redirected to her copy of the Blockstack Browser. If the user has redirected to her copy of the Blockstack Browser. The Blockstack sign-in dialog a user sees depends on
signed into the DApp previously. The actual Blockstack sign-in dialog depends on whether the user already has an existing Blockstack Browser session for their current device.
whether the user already has an existing session in the Blockstack Browser.
<img src="images/kingdom_notin.png" alt=""> <img src="images/kingdom_notin.png" alt="">
Alice can choose to authenticate as one of her Blockstack IDs by selecting the Signing in with an identity is the means by which the user grants the DApp access. Access depends on the scope requested by the DApp. The default `store_write` scope allows the DApp to read the user profile and read/write user data for the DApp. Data is encrypted at a unique URL on a Gaia storage hub.
ID and clicking the **Approve** button. The Blockstack Browser shows Alice an approval dialog with information about your app including:
Alice can choose to authenticate and sign into the DApp with one of her Blockstack IDs by selecting the
ID. The Blockstack Browser shows Alice an approval dialog with information about the access the DApp requests:
* The origin your app was served from * The origin your app was served from
* Your app's name * Your app's name
* Your app's logo * Your app's logo
* The types of permissions and data your app is requesting * The types of permissions and data your app is requesting
Signing in with an identity is the means by which the user grants the DApp access. Access depends on the scope requested by the DApp. The default `store_write` scope allows the DApp to read the user profile and read/write user data for the DApp. Data is encrypted at a unique URL on a Gaia storage hub. When she chooses an ID (or creates a new one), Alice is redirected back to the DApp where she is logged in.
When she clicks approve, Alice is redirected back to the DApp where she is logged in.
## DApp authentication flow ## DApp authentication flow
@ -42,8 +42,7 @@ When she clicks approve, Alice is redirected back to the DApp where she is logge
## Scopes ## Scopes
Scopes define the information and permissions an app requests from the Scopes define the permissions requested from, and that a user accepts, through the sign-in dialog.
user during authentication. This determines the set of permissions a user reads and accepts by choose an ID to sign in with.
DApps may request any of the following scopes: DApps may request any of the following scopes:
| Scope | Definition| | Scope | Definition|
@ -52,16 +51,12 @@ DApps may request any of the following scopes:
| `publish_data` | Publish data so that other users of the app can discover and interact with the user. | | `publish_data` | Publish data so that other users of the app can discover and interact with the user. |
| `email` | Requests the user's email if available. | | `email` | Requests the user's email if available. |
If no `scopes` array is provided to the `redirectToSignIn` or `makeAuthRequest` The permissions scope should be specified through the <a href="https://blockstack.github.io/blockstack.js/classes/appconfig.html" target="\_blank">AppConfig</a> object. If no `scopes` array is provided to the `redirectToSignIn` or `makeAuthRequest`
functions, the default is to request `['store_write']`. functions, the default is to request `['store_write']`.
## blockstack: custom protocol handler ## blockstack: custom protocol handler
The `blockstack:` custom protocol handler is how Blockstack apps send their The `blockstack:` custom protocol handler is how Blockstack apps send their authentication requests to the Blockstack Browser. Users can have a Blockstack Browser installed locally on their device or they can use the web version of the Blockstack Browser. If the Blockstack Browser is installed on a user's computer, it registers itself as the handler for the `blockstack:` customer protocol.
authentication requests to the Blockstack Browser. When the Blockstack Browser
is installed on a user's computer, it registers itself as the handler for the
`blockstack:` customer protocol.
When an application calls When an application calls
[`redirectToSignIn`](http://blockstack.github.io/blockstack.js/index.html#redirecttosignin) [`redirectToSignIn`](http://blockstack.github.io/blockstack.js/index.html#redirecttosignin)
@ -69,8 +64,7 @@ or
[`redirectToSignInWithAuthRequest`](http://blockstack.github.io/blockstack.js/index.html#redirecttosigninwithauthrequest), [`redirectToSignInWithAuthRequest`](http://blockstack.github.io/blockstack.js/index.html#redirecttosigninwithauthrequest),
blockstack.js checks if a `blockstack:` protocol handler is installed and, if so, blockstack.js checks if a `blockstack:` protocol handler is installed and, if so,
redirects the user to `blockstack:<authRequestToken>`. This passes the redirects the user to `blockstack:<authRequestToken>`. This passes the
authentication request token from the app to the Blockstack Browser, which will authentication request token from the app to the local Blockstack Browser. If the local Blockstack Browser is not installed, the call is directed to the web version of the Blockstack Browser.
in turn validate the request and display an authentication dialog.
## Manifest file ## Manifest file
@ -90,8 +84,8 @@ Blockstack apps have a manifest file. This file is based on the [W3C web app man
``` ```
The Blockstack Browser retrieves the manifest file from the app during the The Blockstack Browser retrieves the manifest file from the app during the
authentication process and displays some of the information in it such as the authentication process and displays the information in it such as the
app name and icon to the user. The location of the app manifest file is specific app `name` and to the user during sign in. The location of the app manifest file is specific
in the authentication request token and **must** be on the same origin as the app in the authentication request token and **must** be on the same origin as the app
requesting authentication. requesting authentication.
@ -107,9 +101,9 @@ How you implement CORS depends in part on which platform/service you use to serv
Blockstack Auth makes extensive use of public key cryptography. Blockstack uses ECDSA with the `secp256k1` curve. The following sections describe the three public-private key pairs used in the authentication process: Blockstack Auth makes extensive use of public key cryptography. Blockstack uses ECDSA with the `secp256k1` curve. The following sections describe the three public-private key pairs used in the authentication process:
* how they're generated, * how they're generated
* where they're used * where they're used
* to whom the private key is disclosed. * to whom the private key is disclosed
### Transit private key ### Transit private key

77
_develop/profiles.md

@ -6,18 +6,42 @@ permalink: /:collection/:path.html
{:.no_toc} {:.no_toc}
Blockstack Auth provides single sign on and authentication without third parties or remote servers. On this page, you'll get an overview of authentication from an developer and user perspective. The following topics are covered:
You can use the blockstack.js library to create and register an ID on the Stacks blockchain. This section describes the `Profile` object and contains the following topics:
* TOC * TOC
{:toc} {:toc}
You can use the blockstack.js library to create and register an ID on the Stacks blockchain. Follow these steps to create and register a profile for a Blockchain ID: ## About profiels
Profile data is stored using Gaia on the user's selected storage provider. An example of a `profile.json` file URL using Blockstack provided storage:
```
https://gaia.blockstack.org/hub/1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk/profile.json
```
Follow these steps to create and register a profile for a Blockstack ID:
1. Create a JSON profile object 1. Create a JSON profile object
2. Split up the profile into tokens, sign the tokens, and put them in a token file 2. Split up the profile into tokens, sign the tokens, and put them in a token file
3. Create a zone file that points to the web location of the profile token file 3. Create a zone file that points to the web location of the profile token file
Accounts can have one or more proofs. Proofs are stored under the `account` key in the user's profile data
```js
"account": [
{
"@type": "Account",
"service": "twitter",
"identifier": "naval",
"proofType": "http",
"proofUrl": "https://twitter.com/naval/status/12345678901234567890"
}
]
```
## Create a profile ## Create a profile
@ -60,20 +84,12 @@ try {
const recoveredProfile = Person.fromToken(tokenFile, publicKey) const recoveredProfile = Person.fromToken(tokenFile, publicKey)
``` ```
### Validate profile schema ## Validate profile schema
```js ```js
const validationResults = Person.validateSchema(recoveredProfile) const validationResults = Person.validateSchema(recoveredProfile)
``` ```
## Where profile data is stored
Profile data is stored using Gaia on the user's selected storage provider.
An example of a profile.json file URL using Blockstack provided storage:
`https://gaia.blockstack.org/hub/1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk/profile.json`
## Validate a proof ## Validate a proof
```es6 ```es6
@ -86,15 +102,23 @@ validateProofs(profile, domainName).then((proofs) => {
``` ```
## How proofs are validated ## How proofs are validated
The `validateProofs` function checks each of the proofs listed in the The `validateProofs` function checks each of the proofs listed in the
profile by fetching the proof URL and verifying the proof message. profile by fetching the proof URL and verifying the proof message. Currently supported proof validation services:
- Facebook
- Twitter
- Instagram
- LinkedIn
- Hacker News
- GitHub
The proof message must be of the form: The proof message must be of the form:
``` ```
Verifying my Blockstack ID is secured with the address Verifying my Blockstack ID is secured with the address
1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk 1EeZtGNdFrVB2AgLFsZbyBCF7UTZcEWhHk
``` ```
The proof message also must appear in the required location on the The proof message also must appear in the required location on the
proof page specific to each type of social media account. proof page specific to each type of social media account.
@ -103,7 +127,8 @@ the account identifier/username claimed in the user profile. The
`validateProofs` function will check this in the body of the proof or `validateProofs` function will check this in the body of the proof or
in the proof URL depending on the service. in the proof URL depending on the service.
### Adding additional social account validation services ## Adding additional social account validation services
The `Service` class can be extended to provide proof validation service The `Service` class can be extended to provide proof validation service
to additional social account types. You will need to override the to additional social account types. You will need to override the
`getProofStatement(searchText: string)` method which parses the proof `getProofStatement(searchText: string)` method which parses the proof
@ -125,26 +150,4 @@ static getProofStatement(searchText: string) {
return '' return ''
} }
} }
``` ```
## Currently supported proof validation services
- Facebook
- Twitter
- Instagram
- LinkedIn
- Hacker News
- GitHub
## Profile proof schema
Proofs are stored under the `account` key in the user's profile data
```js
"account": [
{
"@type": "Account",
"service": "twitter",
"identifier": "naval",
"proofType": "http",
"proofUrl": "https://twitter.com/naval/status/12345678901234567890"
}
]
```

19
_develop/storage.md

@ -12,7 +12,7 @@ The Blockstack Platform stores application data in the Gaia Storage System. Tran
{:toc} {:toc}
{% include note.html content="<ul> <li>Blockstack Gaia Storage APIs and on-disk format will change in upcoming pre-releases breaking backward compatibility. File encryption is currently opt-in on a file by file basis.</li> <li>Certain storage features such as and collections are not implemented in the current version. These features will be rolled out in future updates.</li> </ul>" %} {% include note.html content="<ul> <li>Blockstack Gaia Storage APIs and on-disk format will change in upcoming pre-releases breaking backward compatibility. File encryption is currently opt-in on a file by file basis.</li> <li>Certain storage features such as collections are not implemented in the current version. These features will be rolled out in future updates.</li> </ul>" %}
## Creating a file ## Creating a file
@ -23,7 +23,7 @@ You use the <a href="https://blockstack.github.io/blockstack.js/classes/usersess
let options = { let options = {
encrypt: false encrypt: false
} }
blockstack.putFile("/hello.txt", "hello world!", options) blockstack.UserSession.putFile("/hello.txt", "hello world!", options)
.then(() => { .then(() => {
// /hello.txt exists now, and has the contents "hello world!". // /hello.txt exists now, and has the contents "hello world!".
}) })
@ -38,7 +38,7 @@ You use the <a href="https://blockstack.github.io/blockstack.js/classes/usersess
encrypt: true encrypt: true
} }
blockstack.putFile("/message.txt", "Secret hello!", options) blockstack.UserSession.putFile("/message.txt", "Secret hello!", options)
.then(() => { .then(() => {
// message.txt exists now, and has the contents "hello world!". // message.txt exists now, and has the contents "hello world!".
}) })
@ -53,7 +53,7 @@ You use the <a href="https://blockstack.github.io/blockstack.js/classes/usersess
decrypt: false decrypt: false
} }
blockstack.getFile("/hello.txt", options) blockstack.UserSession.getFile("/hello.txt", options)
.then((fileContents) => { .then((fileContents) => {
// get the contents of the file /hello.txt // get the contents of the file /hello.txt
assert(fileContents === "hello world!") assert(fileContents === "hello world!")
@ -69,7 +69,7 @@ You use the <a href="" target="_blank"></a>
decrypt: true decrypt: true
} }
blockstack.getFile("/message.txt", options) blockstack.UserSession.getFile("/message.txt", options)
.then((fileContents) => { .then((fileContents) => {
// get & decrypt the contents of the file /message.txt // get & decrypt the contents of the file /message.txt
assert(fileContents === "Secret hello!") assert(fileContents === "Secret hello!")
@ -86,7 +86,7 @@ the `publish_data` scope during authentication.
app: 'http://BlockstackApp.com' // origin of the app this file is stored for app: 'http://BlockstackApp.com' // origin of the app this file is stored for
} }
blockstack.getFile("/message.txt", options) blockstack.UserSession.getFile("/message.txt", options)
.then((fileContents) => { .then((fileContents) => {
// get the contents of the file /message.txt // get the contents of the file /message.txt
assert(fileContents === "hello world!") assert(fileContents === "hello world!")
@ -95,7 +95,7 @@ the `publish_data` scope during authentication.
## Delete a file ## Delete a file
You use the <a href="https://blockstack.github.io/blockstack.js/classes/usersession.html#deletefile" target="_blank">UserSession.deleteFile</a> You use the <a href="https://blockstack.github.io/blockstack.js/classes/usersession.html#deletefile" target="_blank">UserSession.deleteFile</a> from the application's data store.
```JavaScript ```JavaScript
@ -104,3 +104,8 @@ You use the <a href="https://blockstack.github.io/blockstack.js/classes/usersess
// /hello.txt is now removed. // /hello.txt is now removed.
}) })
``` ```
## Related Information
{:.no_toc}
To learn more about the guarantees provided by Gaia, see [Storage write and read]({{ site.baseurl }}/storage/write-to-read.html#)

4
_includes/sign_in.md

@ -4,7 +4,7 @@ A decentralized application (DApp) and the Blockstack Browser communicate during
![](/storage/images/app-sign-in.png) ![](/storage/images/app-sign-in.png)
When a user chooses to **Sign in with Blockstack** on a DApp, calls the `redirectToSignIn()` method which sends an `authRequest` to the Blockstack Browser. Blocktack passes the token in via a URL query string in the `authRequest` parameter: When a user chooses to **Sign in with Blockstack** on a DApp, it calls the `redirectToSignIn()` method which sends an `authRequest` to the Blockstack Browser. Blockstack passes the token in via a URL query string in the `authRequest` parameter:
`https://browser.blockstack.org/auth?authRequest=j902120cn829n1jnvoa...` `https://browser.blockstack.org/auth?authRequest=j902120cn829n1jnvoa...`
@ -16,7 +16,7 @@ When the Blockstack Browser receives the request, it generates an (`authResponse
The ephemeral key is just used for the particular instance of the application, in this case to sign a sign-in request. It encrypts secrets that need to be passed from the Blockstack Browser to the app during the authentication process. The ephemeral key is just used for the particular instance of the application, in this case to sign a sign-in request. It encrypts secrets that need to be passed from the Blockstack Browser to the app during the authentication process.
The identity address private key is derived from the user's keychain phrase. This key signs the authentication response token for an app to indicate that the user approves sign in to that app. The identity-address private key is derived from the user's keychain phrase. This key signs the authentication response token for an app to indicate that the user approves sign in to that app.
The app private key is application-specific. It is generated from the user's identity address private key using the `appDomain` as input. This app private key is also deterministic, meaning that for a given Blockstack ID and domain name, the same private key is generated each time. The app private key serves three functions: The app private key is application-specific. It is generated from the user's identity address private key using the `appDomain` as input. This app private key is also deterministic, meaning that for a given Blockstack ID and domain name, the same private key is generated each time. The app private key serves three functions:

2
_storage/hello-hub-choice.md

@ -147,7 +147,7 @@ To replace the default login, do the following:
1. Using your favorite editor, open the `public/app.js` file. 1. Using your favorite editor, open the `public/app.js` file.
2. Locate the `redirectToSignIn()` method at line 4. 2. Locate the `redirectToSignIn()` method at line 4.
3. Replace `redirectToSignIn()` method with the `blockstack.redirectToSignInWithAuthRequest(authRequest)` method. 3. Replace `redirectToSignIn()` method with the `blockstack.UserSession.redirectToSignInWithAuthRequest(authRequest)` method.
The `authRequest` is the authentication request generated by `makeAuthRequest()` method. The `authRequest` is the authentication request generated by `makeAuthRequest()` method.

4
overview_auth.md

@ -282,8 +282,8 @@ To check for the presence of this token, your app should call `isSignInPending`.
```js ```js
import * as blockstack from 'blockstack' import * as blockstack from 'blockstack'
if (blockstack.isSignInPending()) { if (blockstack.UserSession.isSignInPending()) {
blockstack.handlePendingSignIn() blockstack.UserSession.handlePendingSignIn()
.then(userData => { .then(userData => {
const profile = userData.profile const profile = userData.profile
}) })

Loading…
Cancel
Save