This is part 3 of Developing Instagram Clone series, other parts are linked below

  1. Developing Instagram Clone: Introduction.
  2. Developing Instagram Clone: Discovery Service.
  3. Developing Instagram Clone: Auth Service
  4. Developing Instagram Clone: Media Service.
  5. Developing Instagram Clone: Post Service.
  6. Developing Instagram Clone: Graph Service.
  7. Developing Instagram Clone: Newsfeed Service.
  8. Developing Instagram Clone: Gateway Service.
  9. Developing Instagram Clone: Front-end Service

Token based authentication

In Monolithic applications, a user provides username and password, the security module validates user credentials and create a session for the user. A session Id is returned to the client and the client stores the session Id in cookies and send it with each request as an identifier for the user.

This approach making the service statefull has an impact on the scalability because a session should be stored for each user, the more users you’ll have the more memory you’ll need.

Also if you divide the app into multiple services, you’ll need to find a way to share the session between services.

In the token based authentication, authentication service generates the token and send it to the client but it doesn’t store it. The client has to send the token with every request in the Authorization header. This token holds the user’s identity information.

Here, I’m using JWT token or Json Web Token, from now on when I will refer to JWT token as simply token.

JWT token structure

Since the token holds user information, it is encoded and encrypted.

A JWT token would look like below

eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZGFtIiwiYXV0aG9yaXRpZXMiOlsiVVNFUiJdLCJpYXQiOjE1OTE2NDQ2NjMsImV4cCI6MTU5MTczMTA2M30.9pR6sK-kJmG6Zm7aWVqNrQy9MZ8ponYKz3Wc3nfKU7MD4oXkifjAEgkB6Uc-Dswp3yjWIiNLrpMd7S9SZ1_D_A

If you notice there are 3 sections in the token separated by dot “.”, these sections are Header.Payload.Signature

1. Header: contains metadata like type of the token and the hashing algorithm that is used in Signature section.

{
"typ": "JWT",
"alg": "HS512"
}

2. Payload: contains user information and token expiration date.

{
  "sub": "adam",
  "authorities": [
    "USER"
  ],
  "iat": 1591644663,
  "exp": 1591731063
}

3. Signature: contains the signature of the token creator, to make sure that the token isn’t changed.

HMACSHA512(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  Secret
)

Auth Service responsibilities

  1. Registering new users.
  2. Validating user credentials and issue a token.
  3. Stores and retrieves users profile.
  4. Manages users.
  5. Sends a message whenever a user created/updated.

Let’s dive deep into code.

Clone the Auth service from GitHub and let’s walk through it.

MongoDB and Apache Kafka (Docker)

Auth service is using MongoDB as the data store for its users, because of scalability, MongoDB has a better performance since it doesn’t have to deal with the overhead of relational databases and it gives a flexibility to evolve the schema as business needs.

Auth service uses Apache Kafka as a way to notify other services whenever user is created, updated or deleted. We can discuss all the “whys” (why Kafka?, why asynchronous? or why notifying other services?) in the comments.

I will be using docker and docker compose for dependencies like MongoDB, Kafka, neo4j, … etc.

If you don’t know what docker and docker compose are, for now, just think of it as a way to have MongoDB and Kafka on your local machine without having to install them on your machine and follow the below instructions.

  1. Install docker and docker compose.
  2. Clone this docker-compose file, comment out Neo4j and Cassandra sections for now.

The file should look like below

version: '3'
services:
  kafka:
    image: wurstmeister/kafka
    container_name: "kafka"
    ports:
      - "9092:9092"
    environment:
      - KAFKA_ADVERTISED_HOST_NAME=127.0.0.1
      - KAFKA_ADVERTISED_PORT=9092
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
    depends_on:
      - zookeeper
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"
    environment:
      - KAFKA_ADVERTISED_HOST_NAME=zookeeper

  mongodb:
    image: mongo:latest
    container_name: "mongodb"
    environment:
      - MONGO_LOG_DIR=/dev/null
    ports:
      - 27017:27017
    volumes:
      - /home/amr/instaMongo:/data/db
#   neo4j:
#     image: neo4j:latest
#     ports:
#      - "7474:7474"
#      - "7687:7687"
#   cassandra:
#     image: cassandra:latest
#     ports:
#       - "7000:7000"
#       - "9042:9042"
#     volumes:
#       - /home/amr/instaCassandra:/var/lib/cassandra

#microservices #jwt #security #cloud #developer

Microservices In Practice: Developing Instagram Clone —Auth Service
7.40 GEEK