Project Link/Auth

From MozillaWiki
Jump to: navigation, search

Authentication

For the first iteration of Project Link we chose to implement a very simple authentication system based on passwords and session tokens with support for a single user only.

All the authentication process is managed by Link boxes (FoxBox). The first time a box is used the user is asked to create a password for the admin user, a bcrypt hash of this password is stored locally in a sqlite database inside the box and a session token is given to the client the user is using to access the box. These session tokens are signed JSON Web Tokens (JWT) that include the user id and user email within their payload and can be used for accessing the box HTTP and websocket endpoints that requires authentication. Once the box setup is completed and the admin user is created, the setup endpoint is hidden. Every new client that needs to get a new session token is required to redirect the user to the box url where the user can introduce her credentials and can be redirected back to the client that will obtain the session token if the authentication process succeeded.

UX

A early draft of the redirection based authentication UI can be found here.

A more detailed spec can be found here (slides 19-end).

Code

Most part of the code related to user management and authentication lives on the fxbox/users repository.

Authenticating requests

For the first iteration of this project, requests that require user authentication must contain a header including a signed JWT.

To obtain a signed JWT you need to make use of the users REST API:

  • If you already have a user, you can request a new session token sending a POST request to the /users/login endpoint including a basic authorization header with username:password encoded in Base64 according to RFC2617.
  POST /users/login HTTP/1.1
  Content-Type: application/json
  Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l
  • If you do not have an admin user registered in the box, you'll need to create one. To do that you need to send a POST request to the /users/setup endpoint with a body including the user name, user email and user password.
  POST /users/setup HTTP/1.1
  Content-Type: application/json
  {
    "email": "user@domain.org",
    "username": "Pepe",
    "password": "whatever"
  }

In both cases successful responses will contain the session token.

  HTTP/1.1 201 OK
  Connection: close
  {
    "session_token":  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJuYW1lIjoidXNlcm5hbWUifQ.IEMuCIdMp53kiUUoBhrxv1GAPQn2L5cqhxNmCc9f_gc"
  }

This token is the one that you need to use to make requests to the boxes' endpoints that requires authentication. Use the JWT with this header:

  {
   "Authorization": "Bearer <jwt>"
  }

For example:

  curl 'http://localhost:3000/api/v1/services' -H 'Accept: application/json' -H 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJraWQiOm51bGwsImFsZyI6IkhTMjU2In0.eyJpZCI6MiwibmFtZSI6ImFkbWluIn0.JNtvokupDl2hdqB+vER15y89qigPc4FviZfJOSR1Vso'

The payload of this token contains the user name and identifier:

  {
     "id": 1,
     "name": "username"
  }

Next steps