<?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: GeekCoding101.com</title>
    <description>The latest articles on DEV Community by GeekCoding101.com (@geekcoding101).</description>
    <link>https://dev.to/geekcoding101</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%2F1332314%2F1e9695bc-3ab4-41bb-bd62-921bf2052119.png</url>
      <title>DEV Community: GeekCoding101.com</title>
      <link>https://dev.to/geekcoding101</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geekcoding101"/>
    <language>en</language>
    <item>
      <title>HTTP Basic Authentication Explained (RFC 7617)</title>
      <dc:creator>GeekCoding101.com</dc:creator>
      <pubDate>Sat, 17 Oct 2026 16:09:54 +0000</pubDate>
      <link>https://dev.to/geekcoding101/http-basic-authentication-explained-rfc-7617-5b7i</link>
      <guid>https://dev.to/geekcoding101/http-basic-authentication-explained-rfc-7617-5b7i</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://geekcoding101.com/posts/a-deep-dive-into-http-basic-authentication" rel="noopener noreferrer"&gt;GeekCoding101&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In this blog post, we will dive into HTTP Basic Authentication, a method rooted in the principles outlined in RFC 7617.&lt;/p&gt;

&lt;p&gt;It’s worth noting that, the RFC specification defines the use of the “Authorization” header in HTTP requests to transmit the credentials. The credentials are typically sent as a Base64-encoded string of the form&amp;nbsp;&lt;code&gt;username:password&lt;/code&gt;. It also describes how servers should respond with appropriate status codes (e.g., 401 Unauthorized) when authentication fails.&lt;/p&gt;

&lt;h1&gt;
  
  
  How HTTP Basic Authentication Works (RFC 7617)
&lt;/h1&gt;

&lt;p&gt;Before writing any code, here is the whole exchange as RFC 7617 defines it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The client requests a protected resource without credentials.&lt;/li&gt;
&lt;li&gt;The server answers &lt;code&gt;401 Unauthorized&lt;/code&gt; with a challenge header that names the scheme and a realm (a label for the protected area):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;   &lt;/span&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;401&lt;/span&gt; &lt;span class="ne"&gt;Unauthorized&lt;/span&gt;
&lt;span class="s"&gt;   WWW-Authenticate: Basic realm="admin area", charset="UTF-8"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The client joins the user ID and password with a single colon, Base64-encodes the result, and sends it in the &lt;code&gt;Authorization&lt;/code&gt; header. For &lt;code&gt;alice&lt;/code&gt; and &lt;code&gt;s3cret&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;   &lt;/span&gt;&lt;span class="nf"&gt;GET&lt;/span&gt; &lt;span class="nn"&gt;/protected&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="s"&gt;   Host: example.com&lt;/span&gt;
&lt;span class="s"&gt;   Authorization: Basic YWxpY2U6czNjcmV0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;The server decodes the value, splits it at the &lt;strong&gt;first&lt;/strong&gt; colon (so the user ID itself cannot contain a colon, but the password can), and checks the pair. A match returns &lt;code&gt;200 OK&lt;/code&gt;; a mismatch returns &lt;code&gt;401&lt;/code&gt; again.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can produce the same header from the command line:&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;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'alice:s3cret'&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt;          &lt;span class="c"&gt;# YWxpY2U6czNjcmV0&lt;/span&gt;
curl &lt;span class="nt"&gt;-u&lt;/span&gt; alice:s3cret https://example.com/protected   &lt;span class="c"&gt;# curl builds the header for you&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few details from RFC 7617 that tutorials often skip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base64 is encoding, not encryption.&lt;/strong&gt; Anyone who sees the header can decode it in one step, so Basic Auth is only acceptable over HTTPS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;charset="UTF-8"&lt;/code&gt;&lt;/strong&gt; is the only charset the server may announce, and tells the client to encode non-ASCII user names and passwords as UTF-8.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No session, no logout.&lt;/strong&gt; The browser caches the credentials for the realm and resends them on every request until the browser is closed; there is no standard way for the server to "log out" a user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSRF exposure.&lt;/strong&gt; Because the browser attaches the credentials automatically, a forged cross-site request carries them too, so state-changing endpoints still need CSRF protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Step 1: Setting Up the Node.js and TypeScript Environment
&lt;/h1&gt;

&lt;p&gt;Please refer to the steps explained in our previous blog post&amp;nbsp;&lt;a href="https://geekcoding101.com/posts/password-authentication-in-node-js-a-step-by-step-guide" rel="noopener noreferrer"&gt;Password Authentication In Node.Js: A Step-By-Step Guide&lt;/a&gt; at&amp;nbsp;&lt;a href="https://geekcoding101.com/posts/password-authentication-in-node-js-a-step-by-step-guide#b71a" rel="noopener noreferrer"&gt;Step 1: Setting Up the Node.js and TypeScript Environment&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Creating the Server
&lt;/h1&gt;

&lt;h2&gt;
  
  
  usersData.ts
&lt;/h2&gt;

&lt;p&gt;In this file, we define a simulated database of users with their hashed passwords using bcrypt. Each user has a&amp;nbsp;&lt;code&gt;username&lt;/code&gt;&amp;nbsp;and a&amp;nbsp;&lt;code&gt;password&lt;/code&gt;&amp;nbsp;field.&lt;/p&gt;

&lt;p&gt;This file acts as our database for the sake of this example.&lt;/p&gt;

&lt;p&gt;The usage of bcrypt also has been explained in &lt;a href="https://geekcoding101.com/posts/password-authentication-in-node-js-a-step-by-step-guide" rel="noopener noreferrer"&gt;Password Authentication In Node.Js: A Step-By-Step Guide&lt;/a&gt;&amp;nbsp;already.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface User {
    username: string;
    password: string;
}

const users: User[] = [];

export default users;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;basicAuthMiddleware.ts&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;This file contains the basic authentication middleware. The middleware is responsible for authenticating users based on the credentials provided in the&amp;nbsp;&lt;code&gt;Authorization&lt;/code&gt;&amp;nbsp;header. It uses bcrypt to compare the provided password with the hashed password stored in the&amp;nbsp;&lt;code&gt;usersData.ts&lt;/code&gt;&amp;nbsp;file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Request, Response, NextFunction } from 'express';
import { Buffer } from 'buffer';
import bcrypt from 'bcryptjs';

interface User {
    username: string;
    password: string;
}

const basicAuthMiddleware = (users: User[]) =&amp;gt; async (req: Request, res: Response, next: NextFunction) =&amp;gt; {
    try {
        const authHeader = req.headers.authorization;
        if (!authHeader) {
            // If no authorization header is provided, send a 401 response with the WWW-Authenticate header
            // so that browser will pop up username/password dialog
            res.setHeader('WWW-Authenticate', 'Basic');
            return res.status(401).json({ error: 'Authorization header missing' });
          }

        const credentials = Buffer.from(authHeader.split(' ')[1], 'base64').toString('utf-8');
        const [username, password] = credentials.split(':');

        const user = users.find((user) =&amp;gt; user.username === username);
        if (!user) {
            return res.status(401).json({ error: 'Invalid username' });
        }

        const isPasswordValid = await bcrypt.compare(password, user.password);
        if (!isPasswordValid) {
            return res.status(401).json({ error: 'Invalid password' });
        }

        next();
    } catch (error) {
        res.status(500).json({ error: 'Internal server error' });
    }
};

export default basicAuthMiddleware;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the interest of security, a production-ready authentication system should not provide explicit feedback on whether the username or password is invalid. However, the code examples provided in this article aim to illustrate the principles of Basic Authentication based on RFC 7617 and are intended for educational purposes. They demonstrate the basic mechanics of authentication but may not fully address all security concerns.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;app.ts&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The&amp;nbsp;&lt;code&gt;app.ts&lt;/code&gt;&amp;nbsp;file will set up the Express server, handles user registration, and protects a route using the basic authentication middleware.&lt;/p&gt;

&lt;p&gt;By implementing authentication in middleware, when the middleware detects invalid credentials, it directly sends the appropriate error response, and the route handler will not be executed.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.ts&lt;/code&gt;&amp;nbsp;imports the users' data from&amp;nbsp;&lt;code&gt;usersData.ts&lt;/code&gt;&amp;nbsp;and creates the middleware by passing the users' data as an argument to&amp;nbsp;&lt;code&gt;basicAuthMiddleware&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;&lt;code&gt;/register&lt;/code&gt;&amp;nbsp;will take&amp;nbsp;&lt;code&gt;{"username": "your_name", "password": "your_password"}&lt;/code&gt;&amp;nbsp;as input.&lt;/p&gt;

&lt;p&gt;The&amp;nbsp;&lt;code&gt;/protected&lt;/code&gt;&amp;nbsp;endpoint is to verify account credentials.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import express from 'express';
import bodyParser from 'body-parser';
import bcrypt from 'bcryptjs';
import basicAuthMiddleware from './basicAuthMiddleware'; // Import the basicAuthMiddleware
import users from './usersData'; // Import the users data

const app = express();
const PORT = 3001;

app.use(bodyParser.json());

// User registration route
app.post('/register', async (req, res) =&amp;gt; {
    try {
        const { username, password } = req.body;

        // Check if the user already exists
        if (users.some((user) =&amp;gt; user.username === username)) {
            return res.status(400).json({ error: 'Username already exists' });
        }

        // Hash the password using bcrypt
        const salt = await bcrypt.genSalt(10);
        const hashedPassword = await bcrypt.hash(password, salt);

        // Save the user in the database (in this example, we're using an in-memory array)
        const newUser = { username, password: hashedPassword };
        users.push(newUser);

        res.status(201).json({ message: 'User registered successfully!' });
    } catch (error) {
        res.status(500).json({ error: 'Internal server error' });
    }
});

// Create the basicAuthMiddleware with the users array as an argument
const authMiddleware = basicAuthMiddleware(users);

// Use the authMiddleware to protect a route
app.get('/protected', authMiddleware, (req, res) =&amp;gt; {
    res.json({ message: 'You have successfully accessed the protected route!' });
});

app.listen(PORT, () =&amp;gt; {
    console.log(`Server is running on http://localhost:${PORT}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Testing the Server
&lt;/h2&gt;

&lt;p&gt;Launch the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx ts-node ./app.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open another terminal and run below command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo '{"username": "testuser01", "password": "testpassword01"}' | http POST http://localhost:3001/register
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It created a user&amp;nbsp;&lt;code&gt;testuser01&lt;/code&gt;&amp;nbsp;in the server with password&amp;nbsp;&lt;code&gt;testpassword01&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let’s try to access the protected URI&amp;nbsp;&lt;code&gt;/protected&lt;/code&gt;&amp;nbsp;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F77v2uhr7l5krze71iupw.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F77v2uhr7l5krze71iupw.webp" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Goto online Base64 encode/decode website (&lt;a href="https://emn178.github.io/online-tools/base64_decode.html" rel="noopener noreferrer"&gt;link here&lt;/a&gt;), we can see the decoding results:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcdzhjjhcvsfl7or2fwi4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcdzhjjhcvsfl7or2fwi4.webp" width="799" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If trying to access from browser, the browser will pop up the username/password verification dialog automatically as below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpcza6o5nyiks68sudl19.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpcza6o5nyiks68sudl19.webp" width="799" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Pros and Cons
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Pros:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Simplicity: HTTP Basic Authentication is easy to implement and understand. It requires minimal additional overhead for client and server implementations.&lt;/li&gt;
&lt;li&gt;Standardization: It is a standardized authentication method supported by most web browsers and server frameworks.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cons:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt;&amp;nbsp;The credentials are Base64-encoded but not encrypted. This means they can be intercepted if transmitted over an insecure network. It’s crucial to use HTTPS to mitigate this issue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Built-in Password Hashing:&lt;/strong&gt;&amp;nbsp;Basic Authentication does not provide built-in mechanisms for securely storing or hashing passwords. Implementing password hashing and salting is the responsibility of the application developer. Like in our article, we have to implement password hashing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited Features:&lt;/strong&gt;&amp;nbsp;It lacks advanced features like multi-factor authentication (MFA) or token-based authentication, which are often needed for more robust security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Session Management:&lt;/strong&gt;&amp;nbsp;Basic Authentication does not manage user sessions. If session management is required, it needs to be implemented separately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Experience:&lt;/strong&gt;&amp;nbsp;While browsers handle the credential prompt, the user experience can be intrusive, especially for web applications.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Is HTTP Basic Authentication secure?
&lt;/h2&gt;

&lt;p&gt;Only over HTTPS. The credentials are Base64-encoded, which anyone can reverse, and they are sent with every request. Over TLS the header is encrypted in transit, which makes Basic Auth acceptable for internal tools, staging sites and machine-to-machine calls, but it still has no MFA, no expiry and no logout.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the format of the Basic Authorization header?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Authorization: Basic &amp;lt;base64(user-id:password)&amp;gt;&lt;/code&gt;, for example &lt;code&gt;Authorization: Basic YWxpY2U6czNjcmV0&lt;/code&gt; for &lt;code&gt;alice:s3cret&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the server send when credentials are missing or wrong?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;401 Unauthorized&lt;/code&gt; with &lt;code&gt;WWW-Authenticate: Basic realm="..."&lt;/code&gt;. The browser shows its login dialog when it sees this header.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Auth vs Bearer tokens?
&lt;/h2&gt;

&lt;p&gt;Basic sends the user's actual password on every request. A Bearer token (for example an OAuth 2.0 access token or a JWT) is a separate, revocable, usually short-lived credential, so a leaked token does far less damage than a leaked password.&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;HTTP Basic Authentication is a straightforward method for securing web resources. It serves well for simple use cases but may not be suitable for applications requiring more advanced security measures.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The source code of this tutorial has been uploaded to&amp;nbsp;&lt;a href="https://github.com/geekcoding101/Authentication101" rel="noopener noreferrer"&gt;GeekCoding101 github repo&lt;/a&gt;&amp;nbsp;as well, feel free to take a look.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the next blog, we will explore more advanced authentication methods, including token-based authentication using JSON Web Tokens (JWT).&lt;/p&gt;

</description>
      <category>security</category>
      <category>authentication</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>OAuth 2.0 Authorization Code Flow, Step by Step</title>
      <dc:creator>GeekCoding101.com</dc:creator>
      <pubDate>Fri, 16 Oct 2026 16:07:42 +0000</pubDate>
      <link>https://dev.to/geekcoding101/oauth-20-authorization-code-flow-step-by-step-3map</link>
      <guid>https://dev.to/geekcoding101/oauth-20-authorization-code-flow-step-by-step-3map</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://geekcoding101.com/posts/oauth-2-0-authorization-code-flow" rel="noopener noreferrer"&gt;GeekCoding101&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Brief Description
&lt;/h1&gt;

&lt;p&gt;The OAuth 2.0 authorization code flow is a secure and widely adopted method for obtaining access tokens to access user resources on behalf of the user.&lt;/p&gt;

&lt;h1&gt;
  
  
  Steps
&lt;/h1&gt;

&lt;p&gt;Here's a summary of the steps in the authorization code flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client Initiation:&lt;/strong&gt; The client application initiates the authorization process by redirecting the user to the authorization server's authorization endpoint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Authentication and Consent:&lt;/strong&gt; The user is prompted to authenticate with the authorization server and grant permission to the client application to access their resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authorization Code Generation:&lt;/strong&gt; Upon successful authentication and consent, the authorization server generates an authorization code and redirects the user back to the client application along with the authorization code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access Token Exchange:&lt;/strong&gt; The client application exchanges the authorization code for an access token by making a request to the authorization server's token endpoint.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access Token Usage:&lt;/strong&gt; The client application uses the access token to access the user's protected resources, such as APIs or data endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To clarify, in the authorization code flow, the authorization endpoint issues an authorization code to the client application upon user consent, not an access token directly.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Flow with Real Requests
&lt;/h1&gt;

&lt;p&gt;Here is what each step looks like on the wire (RFC 6749 section 4.1, with PKCE from RFC 7636). The client is &lt;code&gt;https://app.example.com&lt;/code&gt;, the authorization server is &lt;code&gt;https://auth.example.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Redirect the user to the authorization endpoint.&lt;/strong&gt; The client generates a random &lt;code&gt;state&lt;/code&gt; (CSRF protection) and a random &lt;code&gt;code_verifier&lt;/code&gt;, then sends the browser to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /authorize?response_type=code
    &amp;amp;client_id=my-app
    &amp;amp;redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
    &amp;amp;scope=openid%20profile%20orders.read
    &amp;amp;state=af0ifjsldkj
    &amp;amp;code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
    &amp;amp;code_challenge_method=S256 HTTP/1.1
Host: auth.example.com
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;code_challenge&lt;/code&gt; is &lt;code&gt;BASE64URL(SHA256(code_verifier))&lt;/code&gt;; the verifier itself stays with the client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The user signs in and approves the requested scopes&lt;/strong&gt; on the authorization server's own pages. The client never sees the password.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The server redirects back with a one-time code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt; &lt;span class="m"&gt;302&lt;/span&gt; &lt;span class="ne"&gt;Found&lt;/span&gt;
&lt;span class="na"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://app.example.com/callback?code=SplxlOBeZQQYbYS6WxSbIA&amp;amp;state=af0ifjsldkj&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The client must check that &lt;code&gt;state&lt;/code&gt; matches the value it generated before going further.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The client exchanges the code for tokens&lt;/strong&gt; over a direct back-channel call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="nf"&gt;POST&lt;/span&gt; &lt;span class="nn"&gt;/token&lt;/span&gt; &lt;span class="k"&gt;HTTP&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;
&lt;span class="na"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;auth.example.com&lt;/span&gt;
&lt;span class="na"&gt;Content-Type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;application/x-www-form-urlencoded&lt;/span&gt;
&lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Basic bXktYXBwOm15LXNlY3JldA==&lt;/span&gt;

grant_type=authorization_code
&amp;amp;code=SplxlOBeZQQYbYS6WxSbIA
&amp;amp;redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback
&amp;amp;code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Authorization: Basic&lt;/code&gt; header carries the client ID and secret (see &lt;a href="https://geekcoding101.com/posts/a-deep-dive-into-http-basic-authentication" rel="noopener noreferrer"&gt;HTTP Basic Authentication Explained&lt;/a&gt;); a public client such as a single-page or mobile app has no secret and relies on PKCE alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The server returns the tokens:&lt;/strong&gt;&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;"access_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJhbGciOiJSUzI1NiIs..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"expires_in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"refresh_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tGzv3JOkF0XG5Qx2TlKWIA"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scope"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openid profile orders.read"&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;&lt;strong&gt;6. The client calls the API&lt;/strong&gt; with &lt;code&gt;Authorization: Bearer &amp;lt;access_token&amp;gt;&lt;/code&gt;, and uses the refresh token to get a new access token when it expires.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why PKCE Is Now Recommended for Every Client
&lt;/h1&gt;

&lt;p&gt;PKCE was first designed for mobile apps, which cannot keep a client secret. If an attacker intercepts the authorization code (for example through a malicious app registered for the same redirect URI), they still cannot redeem it, because the token endpoint demands the &lt;code&gt;code_verifier&lt;/code&gt; that only the real client knows. The OAuth 2.0 Security Best Current Practice (RFC 9700) and the OAuth 2.1 draft now recommend PKCE for confidential server-side clients as well, and OAuth 2.1 drops the implicit flow entirely. See &lt;a href="https://geekcoding101.com/posts/oauth-grant-types" rel="noopener noreferrer"&gt;OAuth 2.0 Grant Types Explained&lt;/a&gt; for how the other grant types compare.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why Authorization Code Flow Not Issue Access Token Directly?
&lt;/h1&gt;

&lt;p&gt;The OAuth 2.0 authorization code flow is designed to enhance security and minimize certain risks associated with transmitting sensitive information, such as access tokens, through the user's browser or mobile device.&lt;/p&gt;

&lt;p&gt;Here are some reasons why the authorization endpoint issues an authorization code instead of an access token directly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reduced Exposure of Access Tokens&lt;/strong&gt;: Access tokens are sensitive pieces of information that grant access to the user's protected resources. By issuing an authorization code instead of an access token directly, the authorization server reduces the exposure of access tokens to potentially compromised user agents (such as web browsers or mobile apps). Since the authorization code is short-lived and can only be exchanged for tokens by the client application with its credentials, the risk associated with the interception of the authorization code is lower than if an access token were transmitted directly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Separation of Concerns&lt;/strong&gt;: Separating the authorization process into two steps—obtaining the authorization code and exchanging it for an access token—helps clarify the roles and responsibilities of different components in the OAuth 2.0 flow. The authorization endpoint is responsible for handling user consent and authentication, while the token endpoint is responsible for issuing access tokens based on valid authorization codes and client credentials. This separation enhances the security and maintainability of the OAuth 2.0 protocol.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Support for Additional Security Measures&lt;/strong&gt;: The authorization code flow allows for the implementation of additional security measures, such as client authentication at the token endpoint using client credentials (client ID and client secret), which helps verify the identity of the client application before issuing access tokens. This adds an extra layer of security to the token issuance process and helps prevent unauthorized access to user resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Overall, by issuing an authorization code instead of an access token directly, the OAuth 2.0 authorization code flow aims to improve security, reduce exposure to sensitive information, and provide a clear separation of concerns in the authentication and authorization process.&lt;/p&gt;

&lt;h1&gt;
  
  
  Benefits of Authorization Code Flow
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Enhanced Security: By separating the authorization and token exchange steps, it reduces the risk of exposing sensitive information, such as access tokens, during the authorization process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User Consent: Users have control over which resources the client application can access, ensuring privacy and security.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalability: The authorization code flow is well-suited for a wide range of client types, including web applications, mobile apps, and desktop applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refresh Token Support: It supports the use of refresh tokens, allowing clients to obtain new access tokens without requiring user interaction.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  FAQ
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is the difference between the authorization code and the access token?
&lt;/h2&gt;

&lt;p&gt;The authorization code is a short-lived, single-use value that travels through the browser and is useless on its own. The access token is the credential that calls the API, and it is only ever returned over the back-channel token request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should a single-page app use the authorization code flow?
&lt;/h2&gt;

&lt;p&gt;Yes, with PKCE. The implicit flow that SPAs used to rely on returns the token in the URL and is deprecated by the OAuth 2.0 Security Best Current Practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the &lt;code&gt;state&lt;/code&gt; parameter for?
&lt;/h2&gt;

&lt;p&gt;It ties the callback to the request the client started, so an attacker cannot make the client accept a code from a different authorization (a CSRF attack on the callback).&lt;/p&gt;

&lt;h2&gt;
  
  
  How long does an authorization code live?
&lt;/h2&gt;

&lt;p&gt;RFC 6749 recommends a maximum of 10 minutes, and most providers use much less. It can be redeemed once; a second attempt should make the server revoke the tokens already issued for it.&lt;/p&gt;

</description>
      <category>oauth</category>
      <category>security</category>
      <category>webdev</category>
      <category>authentication</category>
    </item>
  </channel>
</rss>
