<?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: Hamza Hassan Mir</title>
    <description>The latest articles on DEV Community by Hamza Hassan Mir (@hamza_hassan).</description>
    <link>https://dev.to/hamza_hassan</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%2F4147176%2F09528975-a05f-44fa-a8e6-e44edc459ec9.png</url>
      <title>DEV Community: Hamza Hassan Mir</title>
      <link>https://dev.to/hamza_hassan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hamza_hassan"/>
    <language>en</language>
    <item>
      <title>How I Built JWT + OAuth Authentication and Password Security with Bcrypt in My MERN E-Commerce App</title>
      <dc:creator>Hamza Hassan Mir</dc:creator>
      <pubDate>Mon, 28 Sep 2026 13:33:50 +0000</pubDate>
      <link>https://dev.to/hamza_hassan/how-i-built-jwt-oauth-authentication-and-password-security-with-bcrypt-in-my-mern-e-commerce-app-51fa</link>
      <guid>https://dev.to/hamza_hassan/how-i-built-jwt-oauth-authentication-and-password-security-with-bcrypt-in-my-mern-e-commerce-app-51fa</guid>
      <description>&lt;p&gt;Authentication is one of the most important parts of any modern web application.&lt;/p&gt;

&lt;p&gt;While building my &lt;strong&gt;MERN Stack E-Commerce application&lt;/strong&gt;, I wanted users to be able to securely create accounts, log in with their email and password, and also authenticate using Google.&lt;/p&gt;

&lt;p&gt;For this project, I implemented:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JWT-based authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google OAuth authentication&lt;/li&gt;
&lt;li&gt;Bcrypt password hashing&lt;/li&gt;
&lt;li&gt;Protected routes&lt;/li&gt;
&lt;li&gt;Role-based access control&lt;/li&gt;
&lt;li&gt;Secure authentication flows between React and Node.js/Express**&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, I'll explain the concepts behind these technologies and how I used them together in my e-commerce application.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What is JWT?
&lt;/h2&gt;

&lt;p&gt;JWT stands for JSON Web Token.&lt;/p&gt;

&lt;p&gt;JWT is a compact way of securely transferring information between two parties.&lt;/p&gt;

&lt;p&gt;In a web application, JWTs are commonly used to implement stateless authentication.&lt;/p&gt;

&lt;p&gt;The basic flow looks like this:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
  ↓&lt;br&gt;
Login&lt;br&gt;
  ↓&lt;br&gt;
Server verifies credentials&lt;br&gt;
  ↓&lt;br&gt;
Server generates JWT&lt;br&gt;
  ↓&lt;br&gt;
JWT sent to client&lt;br&gt;
  ↓&lt;br&gt;
Client sends JWT with protected requests&lt;br&gt;
  ↓&lt;br&gt;
Server verifies JWT&lt;br&gt;
  ↓&lt;br&gt;
Access granted&lt;br&gt;
What does a JWT look like?&lt;/p&gt;

&lt;p&gt;A JWT usually looks something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xxxxx.yyyyy.zzzzz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It consists of three parts:&lt;/p&gt;

&lt;p&gt;Header.Payload.Signature&lt;br&gt;
Header&lt;/p&gt;

&lt;p&gt;The header contains information about the token, such as the signing algorithm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Payload&lt;/p&gt;

&lt;p&gt;The payload contains claims about the user.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"64f123..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Signature&lt;/p&gt;

&lt;p&gt;The signature allows the server to verify that the token hasn't been modified.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;HMACSHA256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;base64UrlEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
    &lt;span class="nf"&gt;base64UrlEncode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;secret&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing to remember is that a JWT is signed, not encrypted by default.&lt;/p&gt;

&lt;p&gt;Therefore, sensitive information such as passwords should never be placed inside the JWT payload.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;2. How I Used JWT Authentication&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;After a user successfully logs in, my backend generates a JWT.&lt;/p&gt;

&lt;p&gt;For example, using Node.js and the jsonwebtoken package:&lt;/p&gt;

&lt;p&gt;import jwt from "jsonwebtoken";&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1d&lt;/span&gt;&lt;span class="dl"&gt;"&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;The secret is stored in an environment variable rather than directly inside the source code:&lt;/p&gt;

&lt;p&gt;JWT_SECRET=your_secret_key&lt;/p&gt;

&lt;p&gt;The client can then use the token when making authenticated requests.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Authorization: Bearer &lt;/p&gt;

&lt;p&gt;On the server, middleware can verify the token before allowing access to protected routes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authentication required&lt;/span&gt;&lt;span class="dl"&gt;"&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;const decoded = jwt.verify(token, process.env.JWT_SECRET);&lt;/p&gt;

&lt;p&gt;After verification, the application knows which user is making the request.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3. What is OAuth?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;OAuth stands for Open Authorization.&lt;/p&gt;

&lt;p&gt;It is an authorization framework that allows an application to obtain limited access to resources or identity information without requiring the user to give the application their password.&lt;/p&gt;

&lt;p&gt;You may have seen buttons such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Continue with Google&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of creating another password, the user can authenticate through Google.&lt;/p&gt;

&lt;p&gt;This is where OAuth-based authentication becomes useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4. OAuth vs Traditional Authentication&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With traditional email/password authentication:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 ↓&lt;br&gt;
Email + Password&lt;br&gt;
 ↓&lt;br&gt;
Our Application&lt;br&gt;
 ↓&lt;br&gt;
Verify Password&lt;br&gt;
 ↓&lt;br&gt;
Login&lt;/p&gt;

&lt;p&gt;With Google OAuth:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 ↓&lt;br&gt;
Click "Continue with Google"&lt;br&gt;
 ↓&lt;br&gt;
Google&lt;br&gt;
 ↓&lt;br&gt;
User grants permission&lt;br&gt;
 ↓&lt;br&gt;
Google redirects back to our application&lt;br&gt;
 ↓&lt;br&gt;
Application receives authenticated user information&lt;br&gt;
 ↓&lt;br&gt;
User is logged in&lt;/p&gt;

&lt;p&gt;The important advantage is that my application doesn't need to ask the user for their Google password.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;5. Implementing Google OAuth&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For my MERN application, I used Passport.js with Google's OAuth strategy.&lt;/p&gt;

&lt;p&gt;The basic idea is to configure a Google strategy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;passport&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;passport&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Strategy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;GoogleStrategy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;passport-google-oauth20&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;passport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GoogleStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;clientID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;GOOGLE_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;callbackURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/auth/google/callback&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Find or create user&lt;/span&gt;
      &lt;span class="c1"&gt;// ...&lt;/span&gt;
      &lt;span class="nf"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&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;The credentials are stored in environment variables:&lt;/p&gt;

&lt;p&gt;GOOGLE_CLIENT_ID=your_google_client_id&lt;br&gt;
GOOGLE_CLIENT_SECRET=your_google_client_secret&lt;/p&gt;

&lt;p&gt;When a user chooses Google login, Google handles the authentication process and redirects the user back to the application.&lt;/p&gt;

&lt;p&gt;My backend can then find an existing user or create a new account.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;6. What is Hashing?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before implementing password authentication, there is another important concept to understand:&lt;/p&gt;

&lt;p&gt;Hashing.&lt;/p&gt;

&lt;p&gt;Hashing converts data into a fixed-length string using a mathematical function.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;MyPassword123&lt;br&gt;
        ↓&lt;br&gt;
     Hashing&lt;br&gt;
        ↓&lt;br&gt;
$2b$10$...&lt;/p&gt;

&lt;p&gt;Unlike encryption, hashing is designed to be one-way.&lt;/p&gt;

&lt;p&gt;That means we shouldn't be able to simply take a password hash and turn it back into the original password.&lt;/p&gt;

&lt;p&gt;This is extremely important for password storage.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;7. Why Shouldn't We Store Passwords Directly?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine a database containing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;email: &lt;a href="mailto:hamza@example.com"&gt;hamza@example.com&lt;/a&gt;&lt;br&gt;
password: MyPassword123&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If an attacker gains access to the database, they can immediately see the user's password.&lt;/p&gt;

&lt;p&gt;This is why applications should never store plaintext passwords.&lt;/p&gt;

&lt;p&gt;Instead, we store something like:&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;email: &lt;a href="mailto:hamza@example.com"&gt;hamza@example.com&lt;/a&gt;&lt;br&gt;
password:&lt;br&gt;
$2b$10$K8J7...&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
The database contains the hash rather than the original password.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;8. How Bcrypt Helps Secure Passwords&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For my application, I used Bcrypt to hash passwords.&lt;/p&gt;

&lt;p&gt;Bcrypt is specifically designed for password hashing and includes a configurable cost factor that makes password cracking more computationally expensive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;First, &lt;span class="nb"&gt;install &lt;/span&gt;it:

npm &lt;span class="nb"&gt;install &lt;/span&gt;bcrypt

Then import it:

import bcrypt from &lt;span class="s2"&gt;"bcrypt"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;9. Hashing a Password with Bcrypt&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When a user registers, I don't store their password directly.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here:&lt;/p&gt;

&lt;p&gt;10&lt;/p&gt;

&lt;p&gt;is the salt-rounds/cost parameter.&lt;/p&gt;

&lt;p&gt;The resulting hash can then be stored in MongoDB.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The database stores the hash instead of:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MyPassword123&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  10. What is a Salt?
&lt;/h2&gt;

&lt;p&gt;A salt is random data added during password hashing.&lt;/p&gt;

&lt;p&gt;Bcrypt automatically generates and incorporates a salt into the resulting hash.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Password&lt;br&gt;
   +&lt;br&gt;
Random Salt&lt;br&gt;
   ↓&lt;br&gt;
Bcrypt&lt;br&gt;
   ↓&lt;br&gt;
Password Hash&lt;/p&gt;

&lt;p&gt;This helps prevent attackers from efficiently using precomputed hash tables against many users with the same password.&lt;/p&gt;

&lt;p&gt;Another useful property is that two users with the same password can still have different bcrypt hashes because different salts are generated.&lt;/p&gt;


&lt;h2&gt;
  
  
  11. How Login Password Verification Works
&lt;/h2&gt;

&lt;p&gt;One common mistake beginners make is trying to decrypt the stored password hash.&lt;/p&gt;

&lt;p&gt;That's not how password hashing works.&lt;/p&gt;

&lt;p&gt;Instead, when the user logs in, we use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isPasswordCorrect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isPasswordCorrect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;"&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;Bcrypt takes the entered password, applies the appropriate hashing process using the information stored in the hash, and checks whether it matches.&lt;/p&gt;

&lt;p&gt;If it matches:&lt;/p&gt;

&lt;p&gt;Password correct&lt;br&gt;
      ↓&lt;br&gt;
Generate JWT&lt;br&gt;
      ↓&lt;br&gt;
User authenticated&lt;/p&gt;

&lt;p&gt;If it doesn't:&lt;/p&gt;

&lt;p&gt;Password incorrect&lt;br&gt;
      ↓&lt;br&gt;
Reject login&lt;/p&gt;


&lt;h2&gt;
  
  
  12. Putting JWT + Bcrypt Together
&lt;/h2&gt;

&lt;p&gt;This is where the authentication system starts coming together.&lt;/p&gt;

&lt;p&gt;Registration&lt;/p&gt;

&lt;p&gt;When a user registers:&lt;/p&gt;

&lt;p&gt;User enters email + password&lt;br&gt;
             ↓&lt;br&gt;
       Bcrypt hashes password&lt;br&gt;
             ↓&lt;br&gt;
       Hash stored in MongoDB&lt;/p&gt;

&lt;p&gt;The plaintext password is not stored.&lt;/p&gt;

&lt;p&gt;Login&lt;/p&gt;

&lt;p&gt;When the user logs in:&lt;/p&gt;

&lt;p&gt;User enters email + password&lt;br&gt;
             ↓&lt;br&gt;
Find user in MongoDB&lt;br&gt;
             ↓&lt;br&gt;
bcrypt.compare()&lt;br&gt;
             ↓&lt;br&gt;
Password valid?&lt;br&gt;
       ↓           ↓&lt;br&gt;
      Yes          No&lt;br&gt;
       ↓            ↓&lt;br&gt;
Generate JWT     Reject login&lt;br&gt;
       ↓&lt;br&gt;
Return authentication result&lt;br&gt;
Accessing Protected Resources&lt;/p&gt;

&lt;p&gt;Once authenticated:&lt;/p&gt;

&lt;p&gt;Client&lt;br&gt;
  ↓&lt;br&gt;
JWT&lt;br&gt;
  ↓&lt;br&gt;
Protected API endpoint&lt;br&gt;
  ↓&lt;br&gt;
JWT verification middleware&lt;br&gt;
  ↓&lt;br&gt;
Valid token?&lt;br&gt;
  ↓&lt;br&gt;
Controller&lt;/p&gt;

&lt;p&gt;This allows me to protect endpoints such as:&lt;/p&gt;

&lt;p&gt;/api/orders&lt;br&gt;
/api/profile&lt;br&gt;
/api/admin&lt;/p&gt;


&lt;h2&gt;
  
  
  13. Protecting Routes with Middleware
&lt;/h2&gt;

&lt;p&gt;Express middleware can be used to verify JWTs before allowing access to protected endpoints.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;protect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not authenticated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid or expired token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;});&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;Now I can protect routes:&lt;/p&gt;

&lt;p&gt;router.get("/orders", protect, getOrders);&lt;/p&gt;

&lt;p&gt;Only authenticated users can access this endpoint.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Adding Role-Based Access Control
&lt;/h2&gt;

&lt;p&gt;Authentication answers:&lt;/p&gt;

&lt;p&gt;Who are you?&lt;/p&gt;

&lt;p&gt;Authorization answers:&lt;/p&gt;

&lt;p&gt;What are you allowed to do?&lt;/p&gt;

&lt;p&gt;For an e-commerce application, this distinction is important.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Customer&lt;br&gt;
 ├── View products&lt;br&gt;
 ├── Add products to cart&lt;br&gt;
 └── Place orders&lt;/p&gt;

&lt;p&gt;Admin&lt;br&gt;
 ├── Add products&lt;br&gt;
 ├── Update products&lt;br&gt;
 ├── Delete products&lt;br&gt;
 └── Manage orders&lt;/p&gt;

&lt;p&gt;I can include the user's role in the JWT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1d&lt;/span&gt;&lt;span class="dl"&gt;"&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;Then middleware can check the role before allowing access to admin functionality.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Access denied&lt;/span&gt;&lt;span class="dl"&gt;"&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;This gives the application both:&lt;/p&gt;

&lt;p&gt;Authentication&lt;br&gt;
Authorization&lt;/p&gt;




&lt;h2&gt;
  
  
  15. The Complete Authentication Architecture
&lt;/h2&gt;

&lt;p&gt;The authentication system in my MERN e-commerce application can be visualized like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ┌──────────────┐
                │    React     │
                │   Frontend   │
                └──────┬───────┘
                       │
         ┌─────────────┴─────────────┐
         │                           │
   Email/Password                Google OAuth
         │                           │
         ↓                           ↓
   Express API                  Google
         │                           │
         ↓                           ↓
    Bcrypt Verify              OAuth Callback
         │                           │
         └─────────────┬─────────────┘
                       ↓
                 User Authenticated
                       │
                       ↓
                   JWT Token
                       │
                       ↓
             Protected API Routes
                       │
                       ↓
                   MongoDB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  16. Security Lessons I Learned
&lt;/h2&gt;

&lt;p&gt;Building authentication for a real application taught me that authentication isn't just about creating a login page.&lt;/p&gt;

&lt;p&gt;There are several important security practices to keep in mind.&lt;/p&gt;

&lt;p&gt;Never store plaintext passwords&lt;/p&gt;

&lt;p&gt;Always use a password hashing algorithm such as Bcrypt or another modern password-hashing solution.&lt;/p&gt;

&lt;p&gt;Never put passwords inside JWTs&lt;/p&gt;

&lt;p&gt;JWT payloads are not encrypted by default.&lt;/p&gt;

&lt;p&gt;Keep secrets in environment variables&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;JWT_SECRET=...&lt;br&gt;
GOOGLE_CLIENT_SECRET=...&lt;/p&gt;

&lt;p&gt;Don't commit these values to GitHub.&lt;/p&gt;

&lt;p&gt;Validate user input&lt;/p&gt;

&lt;p&gt;Don't blindly trust data coming from the frontend.&lt;/p&gt;

&lt;p&gt;Validate things such as:&lt;/p&gt;

&lt;p&gt;Email format&lt;br&gt;
Password requirements&lt;br&gt;
Required fields&lt;br&gt;
User IDs&lt;br&gt;
Request data&lt;br&gt;
Use HTTPS in production&lt;/p&gt;

&lt;p&gt;Authentication credentials and tokens should be transmitted over encrypted connections.&lt;/p&gt;

&lt;p&gt;Give tokens appropriate expiration times&lt;/p&gt;

&lt;p&gt;A token that remains valid indefinitely increases the impact if it is stolen.&lt;/p&gt;

&lt;p&gt;Protect sensitive endpoints&lt;/p&gt;

&lt;p&gt;Routes such as admin dashboards and order management should require appropriate authentication and authorization.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. What I Built
&lt;/h2&gt;

&lt;p&gt;By combining these technologies, I was able to create a complete authentication system for my MERN e-commerce application.&lt;/p&gt;

&lt;p&gt;The application supports:&lt;/p&gt;

&lt;p&gt;User registration&lt;br&gt;
Email/password login&lt;br&gt;
Bcrypt password hashing&lt;br&gt;
Password verification&lt;br&gt;
JWT-based authentication&lt;br&gt;
Protected API routes&lt;br&gt;
Google OAuth login&lt;br&gt;
User roles&lt;br&gt;
Admin-only functionality&lt;br&gt;
MongoDB user storage&lt;/p&gt;

&lt;p&gt;The biggest thing I learned was that authentication is not a single feature.&lt;/p&gt;

&lt;p&gt;It's a combination of multiple concepts working together:&lt;/p&gt;

&lt;p&gt;Bcrypt&lt;br&gt;
   ↓&lt;br&gt;
Secure password storage&lt;/p&gt;

&lt;p&gt;OAuth&lt;br&gt;
   ↓&lt;br&gt;
Third-party authentication&lt;/p&gt;

&lt;p&gt;JWT&lt;br&gt;
   ↓&lt;br&gt;
Authenticated API requests&lt;/p&gt;

&lt;p&gt;Middleware&lt;br&gt;
   ↓&lt;br&gt;
Protected routes&lt;/p&gt;

&lt;p&gt;Roles&lt;br&gt;
   ↓&lt;br&gt;
Authorization&lt;br&gt;
Conclusion&lt;/p&gt;

&lt;p&gt;Implementing authentication was one of the more valuable parts of building my MERN e-commerce application because it forced me to understand what happens behind a simple Login button.&lt;/p&gt;

&lt;p&gt;Before working on this project, authentication could seem like:&lt;/p&gt;

&lt;p&gt;Login → Done&lt;/p&gt;

&lt;p&gt;But behind that button are several important systems:&lt;/p&gt;

&lt;p&gt;Password Hashing&lt;br&gt;
       ↓&lt;br&gt;
Credential Verification&lt;br&gt;
       ↓&lt;br&gt;
OAuth&lt;br&gt;
       ↓&lt;br&gt;
JWT&lt;br&gt;
       ↓&lt;br&gt;
Middleware&lt;br&gt;
       ↓&lt;br&gt;
Authorization&lt;br&gt;
       ↓&lt;br&gt;
Protected Resources&lt;/p&gt;

&lt;p&gt;Understanding these concepts has made it much easier for me to design authentication systems in other full-stack applications.&lt;/p&gt;

&lt;p&gt;If you're building a MERN application yourself, I highly recommend implementing authentication as a project rather than only learning the concepts theoretically. Building the complete flow makes the relationship between Bcrypt, OAuth, JWT, Express middleware, MongoDB, and React much clearer.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>oauth</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
