DjaoDjin helps your Software-as-a-Service (SaaS) product deliver value sooner and more reliably with a Docker container hosting solution ( See djaodjin.com API reference) bundled together with a user-session firewall (djaoapp) that delivers the two main administrative workflows in a SaaS product:

  • Subscription-based Access Control

    (Pricing, checkout, etc.)

  • Role-based Access Control

    (Managers, contributors, invites, etc.)

Djaoapp extends your server backend code so all the following HTML pages and API end points are already available to your User experience (UX) designers and front-end developers:

  • Authentication
  • Accounts management
  • Billing

There are no third-party keys to manage in the mobile or web front-end, there are no esoteric CORS configuration to setup... From your User Interface (UI) team, all calls to the djaoapp API looks exactly like a call to your business logic API.

If you are writing code in Django, you could integrate the various apps that make up djaoapp directly into a monolithic Web application since all of djaoapp code base is open source. You would though loose on what makes a microservice approach where your business logic and the SaaS administrative logic are their own distinct process:

  1. Security managed in one place
  2. Regulatory compliance (GDPR et al.)
  3. Separate development teams with their own focus

Let's see a high-level view of the HTTP request pipeline and why the microservice approach is the way to build modern SaaS products, then dive into how to integrate djaoapp with your business logic backend.

The HTTP request pipeline ...

Let's assume you have a SaaS product that helps users manage their todo list.

Djaoapp immediately adds 3 ways for users to authenticate with your SaaS product and all the appropriate pages for users to manage their credentials.

  • Session Cookies
  • JSON Web Tokens
  • API Keys

Let's assume you decided to authenticate a user named Xia through a POST request to /api/auth/. At this point, your backend business logic has nothing to do. Everything is handled by djaoapp and a valid token is returned to the browser.

Now your front-end user interface (UI) is doing a GET request to the backend server passing the authentication token along, to retrieve the user profile information (ex. GET /api/users/xia/). Again, your backend business logic has nothing to do. Djaoapp checks that the authenticated user (i.e. xia) has permissions to access the profile information and returns it.

Your front-end user UI is now doing a GET request to the backend server to retrieve the todo list for Xia (ex: GET /api/todos/xia/). This is an actual call to the value proposition of your SaaS product. The HTTP request flows through djaoapp which:

  1. checks the authenticated user has permissions to make that request (see defining access rules).
  2. retrieves personal information from djaoapp database about the authenticated user (full name, roles, etc.)
  3. encodes the authenticated user personal information into either a session cookie or a JSON Web Token
  4. forwards the original HTTP request, modified to include the previously generated session data as HTTP Headers. (there is a Testing section under the Rules dashboard that will generate headers passed to your backend.)

Once your backend server receives the djaoapp forwarded request, it will decode the session data with its DjaoDjin secret key (see Frameworks integration) and process the request according to your business logic.

Example
GET /api/todos/xia/ HTTP/1.1
Authorization: Bearer <JWT>

Code inside djaoapp is triggered that decodes <JWT> to

{
  "username": "xia"
}

After djaoapp applies the access rules (defined for your backend logic in the Rules dashboard), it decides to forwards the request as:

GET /api/todos/xia/ HTTP/1.1
Authorization: Bearer <JWTBackend>

Where <JWTBackend> can be verified with your DjaoDjin secret key and the session data decodes to:

{
  "username": "xia",
  "roles": {
    "manager": [{
      "slug": "xia",
      "printable_name": "Xia Lee",
      "subscriptions": [{
        "plan": "open-space",
        "ends_at": "2018-12-31T09:00:00Z"}]
    }]
  }
}

The above examples is interpreted as: “A request user xia is a manager of the billing profile xia, itself subscribed to the open-space plan.”

Frameworks integration

When your hosting your business logic as a Docker container on djaodjin.com, all HTTP requests fall through djaoapp first before reaching your application. The need for encryption and signature is somewhat less. None-the-less it is good practice. In case you are hosting your application yourself on the open Internet and rely on djaoapp as a reverse proxy, you will need to fully aware of the trade-off between using encrypted cookies and JSON Web Tokens.

Djaoapp is able to decorate HTTP requests it forwards to your application using two protocols.

  • Authorization HTTP Header (Bearer JWT)
  • Cookie HTTP Header (sessionid=encrypted)

You can set which one is used in the Rules dashboard under Web application. You also have the ability to test the headers generated under the Testing section.

Authorization HTTP Header

Using the JWT-based session backend in the Rules dashboard, djaoapp decorates the forwarded HTTP request with a Authorization header that contains Bearer and a JSON Web Token signed with your DjaoDjin secret key.

We provide libraries that make it straightforward to integrate the djaoapp session manager in front of many popular frameworks.

Django

Here's how to use the Authorization header protocol in Django with djaodjin-deployutils

Modify your settings.py as such:

  INSTALLED_APPS = (
+    'deployutils.apps.django',
  )

  MIDDLEWARE_CLASSES = (
-    'django.contrib.sessions.middleware.SessionMiddleware',
+    'deployutils.apps.django.middleware.SessionMiddleware',
  )

+ SESSION_ENGINE = 'deployutils.apps.django.backends.jwt_session_store'

+ AUTHENTICATION_BACKENDS = (
+     'deployutils.apps.django.backends.auth.ProxyUserBackend'
  )

+ DJAODJIN_SECRET_KEY = "Your secret key"

Deployutils also contains a few Mixins that you can extends in your Views in order to access the session data:

Cookie HTTP Header

Djaoapp encrypts the JSON session data with an AES passphrase associated with your server in the Rules dashboard. The resulting encrypted text is compatible with openssl. It can be decrypted with the following command:

$ echo encrypted-text | openssl aes-256-cbc -d -a -k passphrase -p

Djaoapp then replaces the sessionid Cookie with the encrypted JSON session information and forwards the request to your server.

Your server decrypts the sessionid Cookie, then retrieves the information necessary to build a response from the JSON encoded session.

The full Python source code for the decrypt function is available as open source. Assuming you are a lazy hacker, you can even execute openssl through a shell command (though we will deny having suggested the idea).

$ openssl aes-256-cbc -d -a -k passphrase < encrypted-text

We also provide libraries that make it straightforward to integrate the djaoapp session manager in front of many popular frameworks.

Django

Here's how to use the encrypted Cookie header protocol in Django with djaodjin-deployutils

Modify your settings.py as such:

  INSTALLED_APPS = (
+    'deployutils.apps.django',
  )

  MIDDLEWARE_CLASSES = (
-    'django.contrib.sessions.middleware.SessionMiddleware',
+    'deployutils.apps.django.middleware.SessionMiddleware',
  )

+ SESSION_ENGINE = 'deployutils.apps.django.backends.encrypted_cookies'

+ AUTHENTICATION_BACKENDS = (
+     'deployutils.apps.django.backends.auth.ProxyUserBackend'
  )

+ DJAODJIN_SECRET_KEY = "Your secret key"