JSON Web Tokens (JWTs)

JSON Web Token is an open standard that defines a compact and self-contained way for securely transmitting digitally signed information between parties as a JSON object.

Compact: it can be sent through an URL, POST parameter, or inside an HTTP header.

Self-contained: the payload has all the necessary information about the user.

Structure of JWT

JWTs contain three parts separated by a dot(.) and they are:

  • Header
  • Payload
  • Signature

So the JWT look like this:

hhhhhhhh.pppppppp.sssssssssss

Each part is Base64url encoded.

Header

The header usually has two parts:

  • The type of the token
  • The hashing algorithm used in signing the token

The image below shows an example of a header

alg: is the algorithm used for signing the token, and here it is the HMAC SHA256
typ: is the type of the token which is always JWT

Payload

The second part of the JWT. It contain claims, which are information about an entity and other data.

Claims are three types: registered (predefined claims), public (User defined), and private(custom claims used to share information between parties).

The image below present an example of a payload

The information contained in the payload are protected against tampering and modification, but they can be read by anyone because they are encoded not encrypted. So you should not put any secret information in the payload unless you encrypt them.

Signature

The signature is the third part of the JWT. it can be created by taking the base64 encoded header, the base64 encoded payload, a secret, the algorithm specified in the header and sign that.

Example:

{
HMACSHA256 (base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret)
}

The algorithm used in the previous example is the HMAC SHA256.

An Asymmetric hashing algorithm with a public/private key pair can also be used like RSA.

How JWT work

The image below describes how the JWT is used in authentication.

Implementation

There are libraries for implementing JWT in many different programming language. Every programming language has multiple libraries, and they differ in the syntax.

Java JWT example

The code below show how JWT can be created and verified. The library used in this example is jjwt. The signing was done using RS256 algorithm.

// import the necessary packages
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys

// specifying the algorithm and the public/private key pairs
KeyPair keyPair = Keys.keyPairFor(SignatureAlgorithm.RS256)

// creating the signed JWT
String jws = Jwts.builder()
.setHeaderParam("typ", "JWT")
.claim("Name", "Najy")
.claim("admin", true)
.signWith(keyPair.getPrivate())
.compact();




// Verifying the JWT
try{
Jws jws1;
jws1 = Jwts.parser()
.setSigningKey(keyPair.getPublic())
.parseClaimsJws(jws);
out.println("Signature verified, The JWT can be trusted");
out.println("Header: " + jws1.getHeader());
out.println("Payload: " + jws1.getBody());

} catch (Exception ex){ // in case JWT was altered
  out.println("Error: " + ex.getMessage());
}

References

https://jwt.io/introduction/

https://auth0.com/learn/json-web-tokens/

https://en.wikipedia.org/wiki/JSON_Web_Token

https://github.com/jwtk/jjwt

Couchbase

Couchbase Server  is an open source NoSQL document based database that is optimized for interactive web applications. It provides programmatic access to Couchbase server through the SDKs of the different programming languages.

It has a query language known as N1QL, which has a structure composed of statements, expressions, and comments.

Installation

To install latest version of Couchbase in Ubuntu 16.04 (xenial):

First, download Couchbase server from here. Make sure you choose ubuntu 16.04 as the operating system.

Then reload the local package database.

Install Couchbase Server using the following command:

where ./ is the path to the Couchbase server package and * is the version of the package that you have downloaded.

If dpkg reports any errors about missing dependencies, run the following command to download and install them:

Once installation is complete, Couchbase Server will start automatically.

Getting started with Couchbase

Open this link to access the Couchbase Server Web Console.

Enter the username and password that you have provided during installation and click sign in.

Cluster Dashboard

After signing in successfully, you will be forwarded to Cluster Dashboard.

The Cluster Dashboard provides a graphical summary of the current state of your Couchbase cluster.

Click on Buckets in the left-hand navigation bar to go to the bucket screen. On the bucket screen, click on “Add Bucket” to add a new bucket.

Give it a name and determine memory quota then click “Add Bucket”

After adding a bucket, go to “Query” screen to create primary index for your bucket. Use the following query:

CREATE PRIMARY INDEX ON `bucket_name` USING GSI;

Replace `bucket_name` with the name that you have given to your bucket. Then Execute.

You have successfully created your first bucket.


Using Java SDK with a java application

First, download Java SDK from here.

Then extract the zip file and add the following jars to your project:

  • couchbase-java-client:2.6.2
  • couchbase-core-io:1.6.2
  • rxjava:1.3.7
  • opentracing-api:0.31.0

The code segment below describes how the Java SDK can be used for some common operations (described in comments):

import com.couchbase.client.java.*; import com.couchbase.client.java.document.*; import com.couchbase.client.java.document.json.*; import com.couchbase.client.java.query.*;

public class Example {
  public static void main(String[] args) throws Exception {

// Initialize the Connection
  Cluster cluster = CouchbaseCluster.create("localhost");
cluster.authenticate("username", "password"); Bucket bucket = cluster.openBucket("bucketname");


// Create a JSON Document JsonObject arthur = JsonObject.create() .put("name", "Arthur") .put("email", "kingarthur@couchbase.com") .put("interests", JsonArray.from("Reading", "Sport"));

// Store the Document bucket.upsert(JsonDocument.create("u:king_arthur", arthur));


// Load the Document and print it
// Prints Content and Metadata of the stored Document
System.out.println(bucket.get("u:king_arthur"));


// Create a N1QL Primary Index (but ignore if it exists) bucket.bucketManager().createN1qlPrimaryIndex(true, false);


// Perform a N1QL Query
N1qlQueryResult result = bucket.query(N1qlQuery.parameterized("SELECT name FROM `bucketname` WHERE $1 IN interests", JsonArray.from("Sport")));

// Print each found Row
for (N1qlQueryRow row : result) {

// Prints {"name":"Arthur"}
System.out.println(row);

   }
  }
}

References

https://docs.couchbase.com/server/current/install/ubuntu-debian-install.html

https://docs.couchbase.com/server/current/manage/manage-buckets/create-bucket.html

https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/createprimaryindex.html

https://docs.couchbase.com/java-sdk/2.7/start-using-sdk.html