Version: v0.3

Quickstart

ORY Kratos has several moving parts and getting everything right from the beginning can be challenging. This getting started guide will help you install ORY Kratos and some additional dependencies so that you can see how ORY Kratos works.

Please be aware that this guide is not a replacement for studying the docs. You must understand core concepts and APIs to use ORY Kratos productively. This is merely a guide to get you set up with some examples.

Use case: You want login and registration for your Application

This section gives you some context on what we want to achieve and what tools we need for that. You will also learn about the network set up we picked for this guide.

This quickstart guide operates on the assumption that we are writing a NodeJS app called SecureApp. This app is using nothing fancy - some ExpressJS and a bit of HTML Templating using Handlebars. We do want to use TypeScript but only because it's more readable - not because we're doing anything out of the ordinary!

You could pick any technology here, of course. This works with Swift, ReactJS, or Angular (client side) as well as with PHP, Ruby, Python, Java (server side) - you name it! We picked NodeJS + TypeScript because we believe it is the easiest to understand, and because JavaScript and NodeJS are universally understood and easy to install.

We don't really know what SecureApp should do one day. But we do know that it will have some type of dashboard and that it needs users, therefore we need:

  • Login
  • Logout
  • Registration
  • Profile management ("update first name", "update avatar ...")
  • Credentials Management ("add a new recovery email", "change password", "...")
  • Account Recovery ("password reset")
  • Two Factor Authentication with Google Authenticator
  • "Sign in with Google" and "Sign in with GitHub"

and of course:

  • A dashboard that shows "Hello {{ firstName }} {{ lastName }}, your birthday is on {{ birthday }}!". It is only visible when the user is signed in!

Setup

As you might already know, ORY Kratos is API-only. It does not have a UI or HTML Templating Engine. We will implement all the user-facing UIs (dashboard, login, registration, ...) in our NodeJS SecureApp!

To ensure that no one can access the dashboard without prior authentication (login), we can use a small piece of code (here ExpressJS) to do that:

// Import the ORY Kratos SDK. SDKs are available for all popular programming
// languages!
//
// We will add examples for other programming languages here soon!
import { KratosPublicSDK } from '@oryd/kratos-client';
// You can use protect as a middleware for expressJS:
//
// import express from 'express'
// const app = express()
// app.get("/dashboard", needsLogin, dashboard)
//
const needsLogin = (req, res, next) => {
new KratosPublicSDK('https://public.ory-kratos')
.whoami(req)
.then(({ body }) => {
req.user = { session: body };
next();
})
.catch(() => {
res.redirect('/login');
});
};
info

ORY Kratos is not just an API, it uses cookies, HTTP redirects, Anti-CSRF Tokens and more so you don't have to!

Because our SecureApp and ORY Kratos need to share cookies, in order for Anti-CSRF Tokens and Login Session to work, we will set up path with forwards requests to ORY Krato's Public API. If a HTTP Request to https://my-secureap/.ory/kratos/public/self-service/browser/flows/login is made, we forward (like a proxy) the request to https://public.ory-kratos/self-service/browser/flows/login and pipe the response back to the initial HTTP Request:

import express from 'express';
import request from 'request';
const app = express();
const pathPrefix = '/.ory/kratos/public';
app.use(pathPrefix + '/', (req, res) => {
const url = 'https://public.ory-kratos' + req.url.replace(pathPrefix, '');
// Uses the request library to forward the request to ORY Kratos
req.pipe(request(url, { followRedirect: false })).pipe(res);
});
// ...
// app.get("/dashboard", needsLogin, dashboard)
// ...

ORY Kratos does not ship with an administrative user interface. You must implement that yourself or choose the ORY Cloud offering (to be announced). In this quickstart, we will use ORY Kratos CLI (Command Line Interface) to interact with ORY Kratos' Administrative APIs.

The quickstart also comes with MailSlurper, a mock SMTP server the demo uses to show how e.g. email verification works.

Clone ORY Kratos and run it in Docker

To get this example working, you will need Git and Docker, and Docker Compose installed on your system. No other dependencies are required. Before you start, make sure that Docker has enough disk space.

tip

This tutorial uses Docker-Compose volumes which have reported to run out of disk space. Check the remaining disk space using docker system df. If the volumes are above the 85% threshold, prune old Docker objects before you start!

tip

If you encounter build errors (e.g. network timeout), make sure that the network is running correctly and run macke docker again. If the problem persists, feel free to open an issue.

Let's clone ORY Kratos and run docker-compose:

git clone https://github.com/ory/kratos.git
# or if you have git+ssh set up:
# git clone git@github.com:ory/kratos.git
cd kratos
git checkout v0.3.0-alpha.1
make quickstart
# or if you don't have make installed:
docker pull oryd/kratos:latest-sqlite
docker pull oryd/kratos-selfservice-ui-node:latest
docker-compose -f quickstart.yml -f quickstart-standalone.yml up --build --force-recreate

This might take a minute or two. Once the output slows down and logs indicate a healthy system you're ready to roll! A healthy system will show something along the lines of (the order of messages might be reversed):

kratos_1 | time="2020-01-20T14:52:13Z" level=info msg="Starting the admin httpd on: 0.0.0.0:4434"
kratos_1 | time="2020-01-20T14:52:13Z" level=info msg="Starting the public httpd on: 0.0.0.0:4433"
note

There are two important factors to get a fully functional system:

  • You need to make sure that ports 4455, 4433, 4434, 4436 > are free.
  • Make sure to always use 127.0.0.1 as the hostname, never use localhost! This is important because browsers treat these two as separate domains and will therefore have issues with setting and using the right cookies.

You might notice that no database is being used in this example. ORY Kratos supports SQLite, PostgreSQL, MySQL, and CockroachDB as database backends. For the quickstart, we're mounting a persistent volume to store the SQLite database in. Future guides will explain how to set up a production system!

Network Architecture

This demo makes use of several services / Docker Images:

  1. ORY Kratos
  2. The SecureApp - an example application written in NodeJS that implements the login, registration, logout, ..., and dashboard screen.
  3. An SMTP server with which ORY Kratos can send E-Mails with. We will use MailHog, a minimalistic SMTP throaway server with an easy UI.

To better understand how everything is wired, let's take a look at the network configuration. This assumes that you have at least some understanding of how Docker (Compose) Networks work:

User Login and Registration Network Topology

As already explained, we're proxying requests to ORY Kratos' Public API. We are doing this because that way all requests are going to and coming from the same hostname. This avoids common cross-domain issues with cookies.

Perform registration, logout, login

Enough theory, it's time to get this thing going! Let's start by trying to open the dashboard - go to 127.0.0.1:4455/dashboard. You will probably notice that you're ending up at the login endpoint:

Login screen of your secured app

Looking at the network stack, you can see two redirects happening:

Network trace of your secured app

The first redirect from http://127.0.0.1:4445/dashboard to http://127.0.0.1:4455/.ory/kratos/public/self-service/browser/flows/login is initiated because the browser does not have a valid authentication (login) session yet. The redirect points to one of ORY Krato's APIs used for logging in browser-based applications. ORY Kratos does some security checks and prepares form data and redirects the browser to http://127.0.0.1:4445/auth/login, appending a ?request=... query parameter. The endpoint at /auth/login (which belongs to our SecureApp) then fetches data important for rendering the forms from ORY Krato's Admin API:

$ curl http://127.0.0.1:4434/self-service/browser/flows/requests/login?request=<request-id>
{
"id": "27aa98bc-a074-418f-96fa-8b8146050209",
"expires_at": "2020-01-20T21:10:12.7365393Z",
"issued_at": "2020-01-20T21:00:12.7365532Z",
"request_url": "http://127.0.0.1:4455/self-service/browser/flows/login",
"methods": {
"password": {
"method": "password",
"config": {
"action": "http://127.0.0.1:4455/.ory/kratos/public/auth/browser/methods/password/login?request=27aa98bc-a074-418f-96fa-8b8146050209",
"method": "POST",
"fields": [
{
"name": "csrf_token",
"type": "hidden",
"required": true,
"value": "Ii8iIEdnn12vVQ2vyz2YaHjmXMUK5eSQgw9pgENGxPjXi1PHC9gOG51x61o2GT9LGvC81ddvmNXYeLvlPxA04g=="
},
{
"name": "identifier",
"type": "text",
"required": true
},
{
"name": "password",
"type": "password",
"required": true
}
]
}
}
}
}

This data is then rendered as an HTML form. This flow also works with Single Page Apps (SPA) and Frameworks like Angular or ReactJS. For more details about the specific flows (login, registration, logout, ...), head over to the concept chapter.

Let's move on to the next flow - registration! Click on "Create an account", which initiates a flow similar to the one we just used:

Registration screen of your secured app

The network trace looks familiar by now:

Registration with network trace screen of your secured app

If we try to sign up using a password like 123456, ORY Krato's password policy will complain:

Registration with network trace screen of your secured app

The error message is coming directly from ORY Krato's API:

$ curl http://127.0.0.1:4434/self-service/browser/flows/requests/registration?request=<request-id>
{
"id": "79349cbd-c785-476a-8db8-d0d71c5b003c",
"expires_at": "2020-01-20T21:17:00.5077381Z",
"issued_at": "2020-01-20T21:07:00.5077527Z",
"request_url": "http://127.0.0.1:4455/self-service/browser/flows/registration",
"methods": {
"password": {
"method": "password",
"config": {
"action": "http://127.0.0.1:4455/.ory/kratos/public/auth/browser/methods/password/registration?request=79349cbd-c785-476a-8db8-d0d71c5b003c",
"method": "POST",
"fields": [
{
"name": "csrf_token",
"type": "hidden",
"required": true,
"value": "+ZQ8x5cVgdtt4xtPIRJXQPKMVU5c/S2Mj2MuudP32vsMME0g26oQnV/H/brcNvBjkJq1XoF3UcnUFPzcr6Eq4Q=="
},
{
"name": "password",
"type": "password",
"required": true
},
{
"name": "traits.email",
"type": "text",
"value": "hello@ory.sh"
},
{
"name": "traits.full_name",
"type": "text"
}
]
}
}
}
}

Setting a password that doesn't violate these policies, we will be immediately redirected to the Dashboard:

SecureApp Dashboard

By using "logout" you will be redirected to the log in screen again an will be able to use the credentials just set up to log in!

Understanding how Login and Registration works

Head over to the Self-Service Flows Chapter for a in-depth explanation of how the individual flows work.

Email Verification

As you've signed up, an email was sent to the email address you used. Because the quickstart uses a fake SMTP server, the email did not arrive in your inbox. You can retrieve the email however by opening the MailSlurper UI at 127.0.0.1:4436.

You should see something like this:

User Email Verification

If not, hard refresh the tab or click on the home icon in the menu bar.

Next, click the verification link. You will end up at the dashboard, with a verified E-Mail Address (check the verified and verified_at field in the JSON Payload):

SecureApp Dashboard

To re-request the verification email, fill out the form at 127.0.0.1:4455/verify.

Configuration Used

You can find all configuration files for this quickstart guide in ./contrib/quickstart and ./quickstart.yml. To understand what each of those individual configuration files are doing, you must consult the other chapters of this documentation.

note

To get a minimal version of ORY Kratos running, you need to set configuration items identity.traits.default_schema_url and dsn. You should also configure urls.*_ui because your users will end up at fallbacks otherwise.

In the future, this guide will support more use cases such as:

  • Use GitHub to login in and sign up

Cleaning up Docker

To clean everything up, you need to bring down the Docker Compose environment and remove all mounted volumes.

docker-compose -f quickstart.yml down -v
docker-compose -f quickstart.yml rm -f -s -v
Last updated on by aeneasr